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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值