And Then There Was One UVALive - 3882 约瑟夫问题变形 递推法

版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。 https://blog.csdn.net/qq_42835910/article/details/89929258

     Let’s play a stone removing game. Initially, n stones are arranged on a circle and numbered 1, . . . , n clockwise  You are also given two numbers k and m. From this state, remove stones one by one following the rules explained below, until only one remains. In step 1, remove stone m. In step 2, locate the k-th next stone clockwise from m and remove it. In subsequent steps, start from the slot of the stone removed in the last step, make k hops clockwise on the remaining stones and remove the one you reach. In other words, skip (k − 1) remaining stones clockwise and remove the next one. Repeat this until only one stone is left and answer its number. 

   分析:本题只关心最后一个被删除的编号,不需要完整的删除过程,可以用递推法求解。假设编号为0~n-1的n

个数排成一圈,从0开始每k个数删除一个,最后留下数字编号记为f(n),则f(1)= 0,f(n)=(f(n-1)+k)%n(因为删除一个元素之后可以把所有元素重新编号)

本题第一个删除为m,则ans = (m - k + 1 + f[n] + n)%n.(把这个数改成1~n之间)。

#include <cstdio>
const int N = 10000 + 5;
int f[N];
int main(int argc, char** argv) {
	int n, k, m;
	while(~scanf("%d%d%d",&n,&k,&m) && n){
		f[1] = 0;
		for(int i = 2; i <= n; i++) f[i] = (f[i-1]+ k) % i;
		int ans = (m - k + 1 + f[n])%n;
		if(ans <= 0) ans += n; //减法模运算,有可能为负和零 
		printf("%d\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42835910/article/details/89929258