1 条题解
-
0
B. Clockwork 题解
题意简述
有 个时钟排成一行,第 个时钟的初始时间为 ()。
每一秒按顺序发生:- 所有时钟时间减 ,若任一变为 则立即失败。
- 你可以移动到相邻时钟或停留。
- 可将当前所在时钟重置为其初始值 。
你可以从任意时钟开始,问是否存在一种策略使过程无限持续(永不失败)。
关键观察
- 每个时钟 的时间每秒减少 ,必须在它变为 之前到达并重置。
- 重置使该时钟时间恢复为 ,相当于“续命”。
- 移动一步需要 秒,因此从某个时钟出发到达另一个时钟所需时间等于它们在序列上的距离。
- 要无限持续,每个时钟必须被周期性重置,且两次重置的时间间隔 (否则中间会归零)。
转化为可行性条件
考虑最坏情况:你必须能够从最左端走到最右端并返回,且保证沿途所有时钟都不会归零。
对于位置 (下标从 开始),它到左端点的距离为 ,到右端点的距离为 。
最危险的情况是:你需要从较远的端点出发,经过 ,再走到另一个端点。
从较远端到 需要 秒,此时 的时间已减少这么多;重置后,你还要离开 去往另一端点,这又需要 秒,在这段时间内 的时间会继续减少。
因此,为了保证 在两次重置之间不会归零,必须满足:
。
由于 是整数,等价于 。算法步骤
对于每个测试用例:
- 读入 和数组 (下标 到 )。
- 遍历 ,计算 。
- 若存在 ,则输出
"NO";否则输出"YES"。
时间复杂度 ,所有测试用例的 总和不超过 ,完全可行。
代码实现(标程)
#include<bits/stdc++.h> using namespace std; int main(){ ios::sync_with_stdio(false),cin.tie(0); int T,n,i,t,flag; for(cin>>T;T>0;T--){ cin>>n; flag=0; for(i=0;i<n;i++){ cin>>t; if(t <= i*2 || t <= (n-i-1)*2) flag=1; } if(flag) cout<<"NO\n"; else cout<<"YES\n"; } return 0; }示例验证
以题目样例为例:
- :,, 通过;,, 通过 → YES。
- :,, 触发失败 → NO。
- :,, 触发失败 → NO。
- :,,;,,;,, → YES。
- :所有位置均满足 → YES。
与题目输出一致。
总结
本题核心是推导出每个时钟必须满足 ,其中 是 到较远端的距离。贪心检查所有位置即可得到答案。
- 1
信息
- ID
- 6237
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 2
- 已通过
- 1
- 上传者