当前位置: 首页 > news >正文

题解:AtCoder AT_awc0101_b A Single Strike of Dominoes

本文分享的必刷题目是从蓝桥云课洛谷AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。

欢迎大家订阅我的专栏:算法题解:C++与Python实现!

附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总


【题目来源】

AtCoder:B - A Single Strike of Dominoes

【题目描述】

There areN NNpillars lined up in a row in front of Takahashi. The durability of thei ii-th pillar from the left isA i A_iAi.

Takahashi simultaneously applies the same forceX XXto all pillars. Each pillar that receives the impact has its durability decreased byX XX.

After that, a chain reaction propagates from left to right. Specifically, when a pillar collapses (its durability becomes0 00or less), the durability of the pillar immediately to its right decreases by an additional1 11. If this causes the right neighbor to also collapse, the durability of the pillar immediately to its right decreases by1 11as well. This chain continues to the right until a pillar does not collapse. Note that if the rightmost pillar collapses, no further chain reaction occurs.

In summary, whether each pillar collapses is determined from left to right by the following rule: in addition to the direct impactX XX, a pillar receives an additional1 11damage if the pillar immediately to its left has collapsed.

Find the minimum value ofX XXrequired to collapse all pillars.X XXmust be a positive integer.

高橋面前有一排N NN根柱子。从左数第i ii根柱子的耐久度为A i A_iAi

高橋同时对所有柱子施加相同的力X XX。每根受到冲击的柱子耐久度减少X XX

之后,连锁反应从左向右传播。具体地,当一根柱子倒塌(耐久度变为0 00或以下)时,其右侧相邻柱子的耐久度额外减少1 11。如果这导致右侧相邻柱子也倒塌,则再往右一根柱子的耐久度也减少1 11。该连锁反应持续向右传播,直到某根柱子没有倒塌为止。注意,如果最右边的柱子倒塌,则不再发生进一步的连锁反应。

总之,每根柱子是否倒塌按从左到右的顺序由以下规则决定:除了直接冲击X XX之外,如果其左侧相邻柱子已经倒塌,则该柱子额外受到1 11点伤害。

求使所有柱子都倒塌所需的最小X XX值。X XX必须是正整数。

【输入】

The input is given in the following format.

N NN
A 1 A_1A1A 2 A_2A2… \ldotsA N A_NAN

  • The first line gives the number of pillarsN NN.
  • The second line givesN NNintegersA 1 , A 2 , … , A N A_1, A_2, \ldots, A_NA1,A2,,ANrepresenting the durability of each pillar, separated by spaces.

【输出】

Print the minimum value of the forceX XXrequired to collapse all pillars in a single line.

【输入样例】

4 2 3 2 4

【输出样例】

3

【核心思想】

  1. 问题分析:给定N NN根柱子的耐久度A i A_iAi,需要找到一个最小的正整数X XX,使得所有柱子倒塌。倒塌规则为:每根柱子先受到X XX的直接伤害,然后从左到右检查,若第i ii根柱子倒塌(耐久度≤ 0 \leq 00),则第i + 1 i+1i+1根柱子额外受到1 11点伤害。该问题具有单调性——若X XX能使所有柱子倒塌,则任何大于X XX的值也一定能。

  2. 算法选择

    • 整数二分:利用"可行性随X XX增大而单调不减"的性质,在值域[ 1 , 10 9 ] [1, 10^9][1,109]上二分查找最小可行X XX
    • 模拟验证(check函数):对于给定的X XX,按照题目规则模拟连锁反应,判断是否能倒塌所有柱子
  3. 关键步骤

    • 二分边界:左边界l = 1 l = 1l=1,右边界r = 10 9 r = 10^9r=109X XX的最大可能值)
    • 二分过程
      • 取中点m i d = ⌊ l + r 2 ⌋ mid = \lfloor \frac{l + r}{2} \rfloormid=2l+r
      • 调用check(mid)模拟验证:
        • 所有柱子先减去X XXb[i] = \max(0, A_i - X)
        • 从左到右传播连锁反应:若b [ i ] = 0 b[i] = 0b[i]=0,则b [ i + 1 ] = max ⁡ ( 0 , b [ i + 1 ] − 1 ) b[i+1] = \max(0, b[i+1] - 1)b[i+1]=max(0,b[i+1]1)
        • 检查是否所有b [ i ] = 0 b[i] = 0b[i]=0
      • check(mid)为真:r = m i d r = midr=mid(尝试更小的X XX
      • check(mid)为假:l = m i d + 1 l = mid + 1l=mid+1(需要更大的X XX
    • 输出l ll(最小可行X XX
  4. 时间/空间复杂度

    • 时间复杂度:O ( N log ⁡ C ) O(N \log C)O(NlogC),其中C = 10 9 C = 10^9C=109X XX的值域范围。每次check模拟O ( N ) O(N)O(N),二分约log ⁡ C \log ClogC
    • 空间复杂度:O ( N ) O(N)O(N),原数组A [ 1.. N ] A[1..N]A[1..N]和临时模拟数组B [ 1.. N ] B[1..N]B[1..N]
  5. 整数二分的核心思想

    • 单调性利用:若X XX可行,则所有X ′ > X X' > XX>X也可行,因此可行解集合具有单调性,适合二分
    • 验证分离:将"寻找最优解"与"验证可行性"分离,通过高效的模拟验证配合二分快速缩小搜索范围
    • 边界处理:使用max(0, ...)防止耐久度变为负数,避免连锁反应过度传播
    • 连锁传播顺序:必须严格从左到右依次判断,因为第i ii根是否倒塌会影响第i + 1 i+1i+1根的状态
    • 适用于具有单调性的最优化问题,将求解转化为"判定问题 + 二分搜索"的经典模式

【算法标签】

#整数二分

【代码详解】

#include<bits/stdc++.h>usingnamespacestd;constintN=500005;// 最大柱子数量intn;// 柱子数量inta[N],b[N];// a[i]: 第i根柱子的原始耐久度, b[i]: 模拟时的临时耐久度// 检查:当施加的力为x时,是否能使所有柱子倒塌boolcheck(intx){// 复制原始耐久度到临时数组,避免修改原数组memcpy(b,a,sizeof(a));// 第一步:所有柱子受到直接冲击xfor(inti=1;i<=n;i++)b[i]=max(0,b[i]-x);// 第二步:连锁反应从左到右传播// 如果第i根柱子倒塌(耐久度为0),则第i+1根额外受到1点伤害for(inti=1;i<n;i++){if(b[i]==0)// 第i根柱子倒塌b[i+1]=max(0,b[i+1]-1);// 右侧相邻柱子额外减1(不低于0)}// 检查是否所有柱子都倒塌(耐久度都为0)for(inti=1;i<=n;i++){if(b[i]>0)// 存在未倒塌的柱子returnfalse;}returntrue;// 所有柱子都倒塌}intmain(){cin>>n;// 读入柱子数量// 读入每根柱子的耐久度for(inti=1;i<=n;i++)cin>>a[i];// 二分查找最小的Xintl=1,r=1e9;// X的范围:[1, 1e9]while(l<r){intmid=(l+r)/2;// 取中间值if(check(mid))// mid可行,尝试更小的Xr=mid;else// mid不可行,需要更大的Xl=mid+1;}// 输出最小的Xcout<<l<<endl;return0;}

【运行结果】

4 2 3 2 4 3
http://www.jsqmd.com/news/1099085/

相关文章:

  • Python数据分析全流程实战:从数据清洗到可视化报告
  • 2026年6月零代码网站搭建与企业无代码建站工具测评:谁更适合你
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 解决音频格式兼容性难题:FlicFlac轻量级音频转换工具深度解析
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析
  • 小动物人工呼吸机
  • 餐饮老板必看:扫码点餐小程序3步搞定,别再让顾客干等了!
  • 终极指南:如何用Steam-auto-crack实现Steam游戏自动破解
  • ai agent框架spring ai/alibaba 源码原理分析(六) agent和组件
  • [C++]内存管理:串顺序存储的内存回收
  • 移动端游戏功耗测试实战:电流、功率、亮度和场景对比
  • ShaderGlass:如何在Windows桌面上实时运行GPU着色器的完整指南
  • 足球口袋教练 HarmonyOS 离线应用实战(03/20):ArkUI 首页仪表盘搭建
  • 企业 GEO 优化完整应用场景
  • 抖音内容监控助手:告别手动刷新,让优质内容主动找你
  • Vue3+ECharts使用渐变堆叠面积图实现图例横向滚动,超出出现滚动条,组件抽离复用,包含图表自适应窗口大小 - 附完整示例
  • 【终章】从靶机到职场:如何写出一份让企业买单的渗透测试报告?
  • MySQL从入门到精通:数据库设计、索引优化与事务隔离实战指南
  • 多目标机动协同:释放网联自动驾驶中的协同潜力
  • 3步实现Photoshop与AI绘图的无缝融合:SD-PPP插件完全指南
  • 学长真实分享|点餐平台网站全套源码+论文,餐饮类课设毕设稳妥选题!
  • 计算机毕业设计之沧州师范学院学生旅游攻略分享平台的设计与实现
  • 【每天认识一个国家 | 伊朗】
  • 销售KPI怎么设计?这套绩效指标体系直接套用
  • 壮志难酬 李昂
  • 如何快速掌握fullPage.js:终极全屏滚动网站开发指南
  • python基础学习-09(文件读写)
  • day4:复合函数与分段函数
  • 2026实测好用!能打通“订单-库存-财务”的S2B2C系统推荐
  • 2026年6月教育咨询公司网站搭建平台怎么选?5款热门建站工具测评对比,含零代码、AI、定制