1 条题解
-
0
题意分析
这是一个基于约瑟夫问题的变种题目。题目描述了一个经典的约瑟夫环淘汰游戏:个人围成一圈,从2号开始每隔1人淘汰1人(即淘汰2,4,6,...),直到只剩1人。Mike记得自己的编号和被淘汰前剩余人数,要求找出满足条件的可能的最小。
解题思路
解题关键在于逆向推导约瑟夫问题的过程。对于给定的和,我们需要找到最小的使得在淘汰过程中,当剩余人时Mike尚未被淘汰。代码中的joseph函数采用递归方式处理:
- 当时直接返回
- 当为偶数时计算一个线性关系
- 当为奇数时分两种情况递归求解
该解法利用了约瑟夫问题的数学性质,通过递归将问题规模不断缩小,最终合并子问题的解。对于每个测试用例,算法要么返回满足条件的最小,要么返回"Impossible"表示无解。时间复杂度主要取决于递归深度,由于每次递归问题规模减半,可以保证较高的效率。
#include<iostream> using namespace std; typedef long long LL; LL joseph(LL m, LL k) { if (m == 1) return 2 * k - 1; else if (m % 2 == 0) { LL n = m / 2 - 1 + k; if (n >= m) return n; else return 0; } else { LL n1 = joseph((m + 1) / 2, k) * 2; LL n2 = joseph((m - 1) / 2, k) * 2 + 1; if (n2 == 1) n2 = 0; if (n1 > 0 && n2 > 0) return min(n1, n2); else return max(n1, n2); } } int main() { LL m, k; while (cin >> m >> k) { if (m == 0 && k == 0) break; LL ans = joseph(m, k); if (ans > 0) cout << ans << endl; else cout << "Impossible" << endl; } return 0; }
- 1
信息
- ID
- 2924
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者