分析:先来说一个贪心策略,我们优先选择砍所剩竹子中高度最大的竹子,因为无论我们怎么砍高度低的竹子都不可能使得高度低的竹子高度变高,从而能够和高度高的竹子一块被砍,相反的,我们砍完高度高的竹子后由于高度变低,所以可能会跟原来高度低的竹子一块被砍,所以这种贪心策略显然是正确的。而且高度相同的连续竹子一定要放在一起砍,这是显然的,一次可以砍完的事情为什么非要分几次呢?有了这个策略我们再来看一下一棵竹子最多会被砍多少次,你可以先按竹子高度最高1e18来算,发现他经过6次就可以砍成高度为1的竹子,也就是说每棵竹子被砍的次数都不会超过6.

那我们可以开一个优先队列,里面存pair类型,第一维是竹子的高度,第二维是竹子的编号,那么我们先把所有的竹子放入优先队列,每次取出一棵竹子,并记录其编号,直到取到一棵竹子高度不等于前一棵竹子的高度或者编号与前一棵竹子编号不是相连的这个时候就将砍的次数+1.注意由于高度是从高到低排的,我没有用结构体排序,所以pair两维都是按照从高到低的规则来进行排序的,所以先出队列的就是编号较大的,只需要进行一下判断高度是否相等以及编号是否连续即可。还有一点需要注意的就是,我们每次取出队头竹子,然后把这个竹子的高度和编号记录一下,用于判断后续竹子是否可以和当前竹子一块被砍,然后就可以直接把当前竹子砍掉并讲砍完后的高度连同其编号一同放入优先队列(前提是竹子被砍后高度不为1),直至队空为止。

最后分析一下复杂度:每棵竹子最多进6次队列,共有n棵竹子,由于队列中最多同时有n棵竹子,所以每次入队都是o(logn)的,所以说总的复杂度就是6*n*logn,是可以通过所有数据的。

下面是代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
typedef pair<long long,int>PII;
priority_queue<PII>q;
int main()
{int n;cin>>n;long long ans=0;for(int i=1;i<=n;i++){long long t;scanf("%lld",&t);if(t!=1)q.push({t,i});}while(!q.empty()){long long t=q.top().first;//记录当前竹子的高度 int r=q.top().second;//记录当前竹子的编号 q.pop();long long l=sqrt(t/2+1);if(l!=1)q.push({l,r});while(!q.empty()&&q.top().first==t&&q.top().second==r-1){r--;q.pop();//将队首竹子pop if(l!=1)q.push({l,r});//将砍完后的竹子放入优先队列 }ans++;//当发现竹子高度不一致或者编号不连续时记录一次砍的次数 }printf("%lld",ans);return 0;
}

下面我们来对上面的方法进行一下优化,就是我们可以先存下来第i棵树还剩j次砍为1时的高度记录为f[i][j],说的有点绕,我举个例子:比如第i棵树高度为15,那么第一次砍完后高度为2,第二次砍完后高度为1。那么还剩一次就能砍为1的高度为2,还剩两次就能砍为1的高度为15.明白了f数组的含义后我们就能够对上面的问题进行简化了,首先可以知道的一点就是当前仅当两棵树在同一层才有可能被同时砍,能被同时砍不仅要求在同一层,还需要要求高度相同且编号相邻,所以我们可以直接遍历每一层,只要发现有相邻的两棵树高度相同我们的砍树次数就可以减少1,一开始的砍树次数就是所有的树都一次一次地砍为1所需要的次数和,利用这样的方法我们就可以优化刚才进入优先队列的o(logn)的复杂度,所以总的复杂度就是6n

下面是代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=200003;
ll f[N][8];//f[i][j]表示第i个数还剩j次砍为1的高度
ll s[8],tt;
int main()
{int n;cin>>n;ll ans=0;for(int i=1;i<=n;i++){ll x;scanf("%lld",&x);tt=0;while(x!=1){s[++tt]=x;//s[i]记录的是当前竹子砍i-1次后剩余的高度x=sqrt(x/2+1);}ans+=tt;for(int j=1;tt>0;j++,tt--)f[i][j]=s[tt];}for(int i=1;i<=7;i++)for(int j=2;j<=n;j++)if(f[j][i]&&f[j][i]==f[j-1][i]) ans--;printf("%lld",ans);return 0;
} 

(第十三届蓝桥杯省赛)试题J:砍竹子(优先队列+模拟)相关推荐

  1. 2022 第十三届蓝桥杯省赛 C/C++ B组 试题与个人题解

    2022 第十三届蓝桥杯省赛 C/C++ B组 试题与个人题解 试题A: 九进制转十进制 本题总分:5分 [问题描述] 九进制正整数 (2022), 转换成十进制等于多少? [答案提交] 这是一道结果 ...

  2. 2022年第十三届蓝桥杯省赛C/C++B组个人题解

    2022年第十三届蓝桥杯省赛C/C++B组个人题解 试题 A: 九进制转十进制(数学) 试题 B: 顺子日期(语文) 试题 C: 刷题统计(模拟) [样例输入] [样例输出] 试题 D: 修剪灌木(找 ...

  3. 2022年十三届蓝桥杯国赛(C/C++大学B组)个人题解

    2022年十三届蓝桥杯国赛(C/C++大学B组)个人题解 更新:成绩出来了,估分50分左右,最后拿了个国二,还差点到国一,有点出乎意料,挺满意了挺满意了. 去年国赛基本都是暴力,最后国三都没拿到(我是 ...

  4. 【蓝桥杯总决赛】第十三届蓝桥杯省赛C/C++B组个人题解

    2022年第十三届蓝桥杯省赛C/C++B组个人题解 试题 A: 九进制转十进制(数学) 试题 B: 顺子日期(语文) 试题 C: 刷题统计(模拟) [样例输入] [样例输出] 试题 D: 修剪灌木(找 ...

  5. 第十三届蓝桥杯省赛C++B组题解

    写在前面 · 本篇题解对应的是第十三届蓝桥杯省赛C++组的B组的第一场 · 所使用的语言时Python3(其实主要看思路.是什么语言不重要

  6. 第十三届蓝桥杯国赛真题 PythonB组 复盘以及获奖感言(国一!!!)

    第十三届蓝桥杯国赛真题 PythonB组 复盘以及获奖感言(国一) 文章目录 第十三届蓝桥杯国赛真题 PythonB组 复盘以及获奖感言(国一)

  7. 第十三届蓝桥杯(Web 应用开发)线上模拟赛第一题

    [Bug 调试]修复网站显示问题 特别说明 第十三届蓝桥杯(Web 应用开发)线上模拟赛依托于蓝桥云课线上实验环境打造,可能与正式比赛所使用线下环境有所不同.线上模拟赛侧重于考生了解比赛题型和体验比赛 ...

  8. 第十三届蓝桥杯省赛 python B组复盘(三道代码题全AC居然省一了)

    第十三届蓝桥杯省赛 python B组复盘(三道代码题全AC居然省一了)

  9. 【第十三届蓝桥杯省赛B组】统计子矩阵 (枚举前缀和+双指针)

    AcWing 4405. 统计子矩阵 来源:第十三届蓝桥杯省赛C++B组 给定一个 N×MN×M 的矩阵 AA,请你统计有多少个子矩阵 (最小 1×11×1,最大 N×MN×M) 满足子矩阵中所有数的 ...

  10. 【蓝桥杯Python组】2022年第十三届蓝桥杯省赛B组Python解题思路详解

    第十三届蓝桥杯省赛B组Python解题思路详解 因为今年采用线上的举办方式进行比赛,所以组委会对题目做了一定的调整,将原来的5道填空+5道编程题变成了2道填空+8道编程题,据说是为了防止抄袭.其实题目 ...

最新文章

  1. Ubuntu 14.04 分区方案
  2. Python 调用C函数
  3. 熔断器---Hystrix
  4. 使用Redis实现分布式锁
  5. 大气的压力竟然能吊起相扑力士!?
  6. C++实现简单走迷宫的代码
  7. Windows下git安装及使用技巧
  8. 【Computer Organization笔记05】运算器基本功能,定点运算器,Am2901的组成与功能,VHDL硬件描述语言
  9. 今天就来分享一招坐着减肥法~ 办公室“久坐族”也同样适用
  10. Oracle / PLSQL函数 - LENGTH和LENGTHB
  11. 算法四:回溯和分支界定
  12. 利用Matlab App Designer简单设计程序
  13. 写给30岁的自己,以及所有即将、正在、已经奔三的朋友们
  14. 中国式的父慈子孝:爸妈用子女旧手机
  15. 登陆页面+匹配数据库+提示登陆成功或失败
  16. 人脸识别系统设计 -- 基于J2判据和FLDA的多分类器的人脸识别系统设计论文报告(三)(附matlab)
  17. 笔记本插入麦克风被识别成耳机怎么办
  18. 【观察】数字化转型再思考,迎接企业IT“新常态”
  19. 我的世界java版hud怎么设置_修改配置文件以关闭HUD和怪物隐身
  20. C# 计算太阳倾角、太阳高度角

热门文章

  1. 批量检测支付宝是否开通
  2. 激荡三十年:银行数据库的发展与变迁
  3. html怎么设置鼠标手势,css怎么设置鼠标手势?
  4. 读 稻盛和夫《干法》
  5. Top Trending Libraries of 2021,PaddleOCR再开源8大前沿顶会论文模型
  6. Data Collection and Storage We noticed that your app requests the user’s consent to access the ....
  7. python关键词排名批量查排名_[代码全屏查看]-Python 批量获取Baidu关键词的排名并入库...
  8. idea 设置全局豆沙绿
  9. 关于“应用程序正常初始化(0xc0150002)失败”问题的解决方案
  10. 2022注册测绘师备考开始 还在不知所措?手把手教你怎么考?