HDU1210 Eddy's 洗牌问题

13 篇文章 0 订阅
Problem Description
Eddy是个ACMer,他不仅喜欢做ACM题,而且对于纸牌也有一定的研究,他在无聊时研究发现,如果他有2N张牌,编号为1,2,3..n,n+1,..2n。这也是最初的牌的顺序。通过一次洗牌可以把牌的序列变为n+1,1,n+2,2,n+3,3,n+4,4..2n,n。那么可以证明,对于任意自然数N,都可以在经过M次洗牌后第一次重新得到初始的顺序。编程对于小于100000的自然数N,求出M的值。
 

Input
每行一个整数N
 

Output
输出与之对应的M
 

Sample Input
  
  
20 1
 

Sample Output
  
  
20

2

对于这道题,首先来找规律;

假设n=4,那么排列就是1-2-3-4-5-6-7-8;经过第一次洗牌,变成5-1-6-2--7-3-8-4,便于寻找规律,排列中间用了两根杠--;

第二次洗牌:7-5-3-1--8-6-4-2;第三次洗牌:8-7-6-5--4-3-2-1;

第四次洗牌:4-8-3-7--2-6-1-5;第五次洗牌:2-4-6-8--1-3-5-7;

第六次洗牌:1-2-3-4--5-6-7-8;至此,在n=4的情况下,经过6次洗牌,排列重新归位。

接下来来追踪某个牌,1的追踪路径在排列中的位置变换是1——2——4——8——7——5——1,循环长度为6;

2的追踪路径:2——4——8——7——5——1——2,循环长度为6;3的追踪路径:3——6——3,循环长度是2;3与1,2均不同,在第二次洗牌之后就已经归位了。

所以这道题求的是每个牌的循环长度的最小公倍数。

每个牌都去算循环长度的话未免有点麻烦,这道题中有个定理,在1经过一系列变换归位时,其他牌也在这时同步归位;

所以只需要追踪1的位置变换即可。

再看上面的假设条件下的1的位置变换:1——2——4——8——7——5——1,不难看出,当位置t在整个排列前半段时,即t<=n时,变换的下一个位置是2*t;

否则,当t在整个排列后半段时,下一个位置则是2(t-n)-1,即2*t-(2*n+1);

而最终当t=1,即回到最初始位置时,就找到了答案。

代码如下:

#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[]) 
{
	int n,t,f,c;
	while(scanf("%d",&n)!=-1)
	{
		t=1;f=0,c=0;
		while(f!=1)
		{
			if(t<=n)
			{
				t=2*t;
				c++;
			}
			else
			{
				t=2*t-(2*n+1);
				c++;
			}
			f=t;
		}
		printf("%d\n",c);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值