1 条题解
-
0
题目理解
这是 ROI 2018 删除数字 问题的解决方案。题目模拟一个删除过程:每轮删除当前序列中每隔 个的数字,求数字 在哪一轮被删除。
代码思路解析
1. 模拟删除过程
代码使用循环模拟每一轮删除:
for (long long i = 1; i <= n; i++) { if (cp < k) break; // 剩余数字少于k个,过程结束 if (cp % k == 0) { // 检查n是否在本轮被删除 cout << i; return 0; } cp -= cp / k; // 计算剩余数字数量 }2. 关键观察
不需要真正维护整个序列,只需要:
cp记录当前轮剩余的数字总数- 每轮删除
cp/k个数字 - 当
cp % k == 0时,最后一个被删除的数字就是本轮最后一个数字
3. 删除规则分析
设当前有
m个数字,编号为1..m:- 删除的数字位置是:
k, 2k, 3k, ... - 如果
m % k == 0,则最后一个数字m会被删除 - 否则最后一个数字
m会保留到下一轮
关键技巧
1. 数量模拟替代序列模拟
不维护具体序列,只维护剩余数字数量
2. 终止条件判断
if (cp < k) break;剩余数字少于 个时过程结束
3. 删除检测
if (cp % k == 0)当剩余数字数量能被 整除时,最后一个数字会被删除
4. 数量更新
cp -= cp / k;每轮删除
floor(cp/k)个数字复杂度分析
时间复杂度:
- 最多循环轮数:(每轮数字数量至少减少 )
- 每轮操作:
- 总复杂度:
空间复杂度:
- ,只用了几个变量
正确性验证
样例验证:
轮次 cp cp%k 删除数量 结果 1 13 1 6 继续 2 7 3 3 4 0 2 找到,输出3 ✓ 边界情况:
- 很大时仍能高效计算
- 时是经典约瑟夫问题变种
- 当 永远不会被删除时输出 0
总结
这个解法巧妙地将问题转化为数学模拟:
- 问题简化:发现只需要跟踪剩余数字数量,不需要具体序列
- 规律发现:当剩余数量能被 整除时,最后一个数字被删除
- 高效模拟:每轮用数学公式更新数量,避免暴力模拟
- 边界处理:正确处理过程终止和找不到的情况
体现了竞赛中模拟题的优化思路,特别是通过数学观察将 模拟优化到 的技巧。
- 1
信息
- ID
- 4357
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者