题目大意
问约瑟夫游戏第m个出局的人的编号。
解题思路
首先需要知道怎么递推求出约瑟夫游戏最后赢家的方法,可以参考这个博客。
对于第m个出局的人,他在第m轮的位置肯定是(k-1)%(n-m+1)+1,然后人数从n-m+1递推到n的过程中,每一步都要把当前赢家的位置往后挪k个并取模,但是题中的数据肯定是不能直接暴力递推的。可以发现其实不是每个位置都需要取模,我们可以求出需要取模之前一共可以加多少次k,然后直接用乘法来加速计算就行了,但是这里有个坑点,就是k等于1的时候,应该直接输出m,否则还是会一步一步的递推。
代码
int main() {
int __; cin >> __;
int kase = 1;
while(__--) {
ll n, m, k; scanf("%lld%lld%lld", &n, &m, &k);
ll now = 0, i = n-m+1;
if (k==1) now = m;
else {
while(i<=n) {
ll t = min((i-now)/k, n-i);
if (t) now = now+t*k, i += t;
else now = (now+k-1)%i+1, ++i;
}
}
printf("Case #%d: %lld
", kase++, now);
}
return 0;
}