题目大意:给出一排 nnn 个竹子的高度,每次操作可以选择连续的,高度相同的竹子,使其高度变为 ⌊⌊H2+1⌋⌋\lfloor \sqrt{\lfloor \frac{H}{2}+1\rfloor} \rfloor⌊⌊2H​+1⌋​⌋,问最少需要执行多少次操作可以使得所有竹子都变成 111

题目分析:最朴素的思路就是去模拟,赛时想到的也是这个思路,但是没时间去写了,就打了个 O(n2logn)O(n^2logn)O(n2logn) 的暴力骗了点分

首先需要知道每次操作的一个性质,根号和除以二相结合,使得 1e181e181e18 的数字没有几次就会下降成 111,这里视为 logloglog 的复杂度是完全可以的

那么模拟的思路就呼之欲出了:

  1. 将序列去重(去掉相邻重复的部分)
  2. 找到最大值,执行一次操作

赛时感觉需要用线段树或平衡树来维护,没有多想,赛后经过帽帽鸽的提醒,发现这个模型可以套用双向链表+堆的思路去实现。简单来说就是对序列维护一个双向链表,对于需要合并的一段,压缩成一个点,扔进堆里每次选择最大值即可,时间复杂度 O(nlog2n)O(nlog^2n)O(nlog2n)

赛后和杨大佬讨论之后发现了另一个思路,对于一个位置 iii 来说,合并带来最直接的影响就是将 i−1i-1i−1、iii、以及 i+1i+1i+1 视为了一个整体,之后的操作实质上也完全可以视为一个整体了。所以我们不妨对于任意一个位置 iii 来说,只关注其两个状态:

  1. 与位置 i−1i-1i−1 合并之,每次需要花费一次操作
  2. 与位置 i−1i-1i−1 合并之,每次借助 i−1i-1i−1 操作即可,无需额外的花费

如何实现呢?因为每个数字下降为 111 的过程必定会产生一个序列,我们只需要关注 i−1i-1i−1 的序列和 iii 的序列,最长公共后缀的长度就好了,妙啊

时间复杂度还是 O(nlog2n)O(nlog^2n)O(nlog2n)

代码:
双向链表+堆

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+100;
int nt[N],pre[N],n;
LL a[N];
bool ban[N];
void del(int x) {ban[x]=true;nt[pre[x]]=nt[x];pre[nt[x]]=pre[x];
}
LL cal(LL x) {return sqrt(x/2+1);
}
void init() {pre[0]=0;nt[n+1]=n+1;for(int i=1;i<=n;i++) {nt[i]=i+1;pre[i]=i-1;}
}
int main() {cin>>n;init();for(int i=1;i<=n;i++) {scanf("%lld",a+i);}priority_queue<pair<LL,int>>q;for(int i=1;i<=n;i++) {if(a[i]==a[i-1]) {del(i);} else {q.push({a[i],i});}}int ans=0;while((int)q.size()>1) {int pos=q.top().second;q.pop();if(ban[pos]) {continue;}if(a[pos]==1) {continue;}ans++;a[pos]=cal(a[pos]);if(a[pos]==a[pre[pos]]) {del(pre[pos]);}if(a[pos]==a[nt[pos]]) {del(nt[pos]);}q.push({a[pos],pos});}cout<<ans<<endl;return 0;
}

思维

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+100;
vector<LL>node[N];
int main() {int n;cin>>n;for(int i=1;i<=n;i++) {LL x;scanf("%lld",&x);while(x>1) {node[i].push_back(x);x=sqrt(x/2+1);}reverse(node[i].begin(),node[i].end());}int ans=0;for(int i=1;i<=n;i++) {int len=(int)min(node[i].size(),node[i-1].size());for(int j=0;j<len;j++) {if(node[i][j]!=node[i-1][j]) {len=j;break;}}ans+=(int)node[i].size()-len;}cout<<ans<<endl;return 0;
}

蓝桥杯 - 试题 J: 砍竹子(双向链表+堆/思维)相关推荐

  1. 2022蓝桥杯省赛——砍竹子

    问题描述 这天, 小明在砍竹子, 他面前有 n 棵竹子排成一排,一开始第 i 棵竹子的 高度为 hi​. 他觉得一棵一棵砍太慢了, 决定使用魔法来砍竹子.魔法可以对连续的一 段相同高度的竹子使用, 假 ...

  2. [蓝桥杯2022初赛] 砍竹子

    题目描述 这天,小明在砍竹子,他面前有 n 棵竹子排成一排,一开始第 i 棵竹子的高度为 hi. 他觉得一棵一棵砍太慢了,决定使用魔法来砍竹子. 魔法可以对连续的一段相同高度的竹子使用,假设这一段竹子 ...

  3. 蓝桥杯 试题 算法训练 无聊的逗 C++ 详解 - 未完善

    题目: 逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中.不过他想到了一个游戏来使他更无聊.他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的 ...

  4. Python 蓝桥杯试题 基础练习 特殊回文数

    Python 蓝桥杯试题 基础练习 特殊回文数 问题描述: 123321是一个非常特殊的数,它从左边读和从右边读是一样的. 输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于 ...

  5. 蓝桥杯试题 数列排序

    蓝桥杯试题 数列排序 问题描述 给定一个长度为n的数列,将这个数列按从小到大的顺序排列.1<=n<=200 输入格式 第一行为一个整数n. 第二行包含n个整数,为待排序的数,每个整数的绝对 ...

  6. 蓝桥杯 试题 算法训练 无聊的逗 C++ 详解

    题目: 逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中.不过他想到了一个游戏来使他更无聊.他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的 ...

  7. 蓝桥杯 试题 算法训练 无聊的逗

    蓝桥杯 试题 算法训练 无聊的逗 问题描述 逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中.不过他想到了一个游戏来使他更无聊.他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘 ...

  8. 蓝桥杯试题 基础练习 十六进制转十进制

    蓝桥杯试题 基础练习 十六进制转十进制 C/C++实现 资源限制 时间限制:1.0s 内存限制:512.0MB 问题描述 从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出. ...

  9. Python 蓝桥杯试题 基础练习 字母图形

    Python 蓝桥杯试题 基础练习 字母图形 问题描述: 利用字母可以组成一些美丽的图形,下面给出了一个例子: ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 这是一个 ...

最新文章

  1. Android Rect 的使用以及与RectF的区别
  2. 腾讯二面挂了,就因为这个...
  3. 打印菱形星号组合C程序
  4. hadoop 批流处理的实现_从T+1到T+0,浅谈PetaBase的实时流式处理
  5. DML,DDL,DCL,DQL的区别
  6. 人力资源SaaS软件“乐才Joy HR”获数百万元战略融资
  7. 一个socket可以绑定多个端口吗_udp绑定端口信息
  8. 2017年WorkApplication牛客网线上机试题
  9. 知名网络安全专家访谈记
  10. 【渝粤教育】国家开放大学2018年秋季 2245T社会福利与保障 参考试题
  11. Word 批量转 PDF脚本
  12. python3GUI--你喜欢的无损音乐下载工具(附源码)
  13. 网站实时监控系统的设计与实现
  14. 腾讯Node.js基础设施TSW正式开源 1
  15. FlinkSQL 读写 MySQL
  16. Git 从入门到放不下
  17. 终端文本编辑神器--Vim命令详解。如何配置使用Vim、Vim插件?
  18. 2020年吉林省考申论指导:解题思路总结
  19. Python开发环境Spyder3安装方法
  20. 小学生计算机房的简笔画,小学生美丽的校园简笔画图片欣赏

热门文章

  1. 评估 | 自动摘要评估
  2. anaconda学习python_python深度学习笔记1-Anaconda软件安装
  3. 带指针C语言代码,C语言指针(示例代码)
  4. MySQL sql99语法—自连接
  5. MySQL分组查询—添加分组后筛选
  6. AQS.addWaiter
  7. CAS单点登录 - 用户登录与校验
  8. SpringMVC的请求-文件上传-单文件上传的代码实现2
  9. 规格参数组查询的代码实现
  10. 数据库-事务并发操作问题及并发的控制