【蓝桥杯每日一题】砍竹子

砍竹子

2024-12-7 蓝桥杯每日一题 砍竹子 STL 贪心

题目大意

这天, 小明在砍竹子, 他面前有 nn 棵竹子排成一排, 一开始第 ii 棵竹子的 高度为 h i h_i hi. 他觉得一棵一棵砍太慢了, 决定使用魔法来砍竹子。魔法可以对连续的一 段相同高度的竹子使用, 假设这一段竹子的高度为 HH, 那么用一次魔法可以 把这一段竹子的高度都变为 [ ⌊ H 2 ⌋ + 1 ] \begin{bmatrix}\sqrt{\lfloor\frac{H}{2}\rfloor+1}\end{bmatrix} [⌊2H⌋+1 ], 其中 [ x ] \begin{bmatrix}x\end{bmatrix} [x] 表示对 x 向下取整。小明想 知道他最少使用多少次魔法可让所有的竹子的高度都变为 1 。

解题思路

这个题使用到了 STL 的技巧,有些不好想,咱们一步一步分析。

  1. 当前值改变的次数是否要加,取决于与它相邻的元素是否相等,这时候我们只看前面相邻的元素。。

  2. 当相邻元素减小到同一个值的时候,只需要计算一次即可,这一次怎么算,就是这些相邻相同的所有元素的对头那个来算,其他的都不算。

  3. 可以通过模拟每一个数的一个变化历程,然后对比前后的数据变化发现那些数是可以变化的。

  4. 举例:

    cpp 复制代码
    7 6 2 4 1 2
    7 2 1     2
    6 2 1     1
      2 1     0
    4   1     1
        1     0
      2 1     1
  5. 根据例子可以观察到每一个数的更新它所贡献的值只有与前一个数的变化历程不同的数的数量,那么就可以通过两个set集合来进行比较。

Accepted
cpp 复制代码
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    int n;
    cin>>n;
    ll res = 0;
    set<ll> pri;
    for(int i = 1;i <= n;i++) {
       ll t;
       cin>>t;
       set<ll> pre;
       while(t > 1) {
           pre.insert(t);
           if(!pri.count(t)) {
               res++;
           }
           t = sqrtl(t/2+1);
       }
       pri = pre;
    }
    
    cout<<res<<endl;
    return 0;
}
思考

这道题还是很难想出来的,必须通过模拟来观察规律求解!!!

备注

想要一起备赛的小伙伴可以私信加我的联系方式!

相关推荐
人道领域几秒前
【LeetCode刷题日记】617.合并二叉树(空间换安全,还是原地省内存)
java·数据结构·算法·leetcode
独自破碎E4 分钟前
机器人Java后端算法笔试题解析
java·windows·算法
计算机安禾7 分钟前
【c++面向对象编程】第45篇:萃取(Traits)技术与策略类:STL源码中的智慧
开发语言·c++
运筹vivo@7 分钟前
3043. 最长公共前缀的长度(Leetcode 每日一题)
c++·算法·leetcode·职场和发展·每日一题
杜子不疼.9 小时前
【C++ AI 大模型接入 SDK】 - DeepSeek 模型接入(上)
开发语言·c++·chatgpt
石山代码10 小时前
C++ 内存分区 堆区
java·开发语言·c++
心中有国也有家11 小时前
cann-recipes-infer:昇腾 NPU 推理的“菜谱集合”
经验分享·笔记·学习·算法
绝知此事11 小时前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
碧海银沙音频科技研究院11 小时前
通话AEC与语音识别AEC的软硬回采链路
深度学习·算法·语音识别
csdn_aspnet12 小时前
Python 算法快闪 LeetCode 编号 70 - 爬楼梯
python·算法·leetcode·职场和发展