Gym

题目链接

题目大意

  问约瑟夫游戏第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;
} 

原文地址:https://www.cnblogs.com/shuitiangong/p/14465672.html