POJ 3517 And Then There Was One (递推,约瑟夫问题变形)

题意:1到n这n个数排成一圈,第一次删除m,以后每k个数删除一次,求最后一个被删除的数。

思路:看了刘汝佳的书,怎么都看不懂,最后自己按照书上的大体思路,自己推了一个和书上不同的公式过了。。

设有n个数字分别是0到n-1,第一次删除0,以后每k个数删除一次,最后被删除的数字是f(n)。那么,f(1)=0,f(n)=(f(n-1)+k-1)%(n-1)+1

因为我们可以把删数字的过程看成这样,在删除n个数字里的0以后,剩下n-1个数,这时要删除编号为(k-1)%(n-1)+1的数。我们不妨把这n-1个数的编号位移一下重新排列,我们将上述的(k-1)%(n-1)+1这个位置看成新的0,然后再删除数字。所以通过观察可以得到递推式:f(1)=0,f(n)=(f(n-1)+k-1)%(n-1)+1最后,因为我们是从m开始删除的,所以最后的答案就是(m-1+f(n))%n+1    (因为原题是1到n,而我们的式子是0到n-1,所以这里经过位置的调整)

#include<cstdio>
#include<cstring>
#define MAXN 10005
int m,k,n,f[MAXN];
int main()
{
	f[1]=0;
	while(~scanf("%d%d%d",&n,&k,&m))
	{
		if(!n && !k && !m) break;
		for(int i=2;i<=n;++i) f[i]=(f[i-1]-1+k)%(i-1)+1;
		printf("%d\n",(f[n]+m-1)%n+1);
	}
	return 0;
}

你可能感兴趣的:(算法,poj,uva,约瑟夫问题变形)