hdu 1210 Eddy's 洗牌问题
来源:互联网 发布:电影资源采集站源码 编辑:程序博客网 时间:2024/05/29 12:39
/...................................................................................................................................................................................................................................................................................................................\
洗牌问题:
很多人都是跟踪第一张牌来完成的,大家会不会证明呢?
定理1:当第一张牌(牌1)回到初始位置时,所有的牌都回到了初始位置。
证明:设有一次操作,某牌在操作前处于位置r(1<=r<=2*N),那么,操作后,如果r原来是前一半的,显然r'=r*2; 否则,r'=(r-n)*2-1,即r'='r*2-(N*2+1);
将两个式子综合,可以得到r'= (r*2)%(N*2+1);
根据同余定理之一 ((i%m)*j)%m=(i*j)%M,可以整理出公式:i次操作后,该牌的位置为:
(r*(2^i))%(N*2+1);其中^表示乘方。
现在,我们假设经过M次操作后,牌1回到了初始位置,即(1*(2^M))%(N*2+1)=1时,再次应用同余定理,可以证明对于任意的k(1<=k<=2*N),有(k*(2^M))%(N*2+1)=k,翻译成自然语言就是:当第一张牌回到初始位置时,所有的牌都回到了初始位置。命题得证。
定理2:一定存在某次操作M,这次操作后,所有的牌都回到了初始位置。
证明:我们已经证明了牌1回到初始位置时,所有的牌都回到初始位置,所以我们只需要证明牌1可以回到初始位置,即(2^M)%(N*2+1)=1一定有正整数解。证明这个定理前我们首先证明这样一个定理:
定理2.1:(2*r)%(2*n+1)==t
当t确定为1到2*n中的某值时(1<t<=2*n),r在1到2*n间有唯一解
因为2*n+1是奇数,我们只要看一下就会发现r到t是一个一一映射,当t为偶数时,显然r=t/2,当t为奇数时,r=(t+1)/2+n,
现在我们来证明定理2。运用反正法,若牌1永远不能回到初始位置,根据鸽笼定理,牌1必然陷入了某个不包含位置1的循环,因为下一状态仅和当前状态有关,当前状态最多只有2*N种,所以显然一定在不超过2*N+1次操作内出现重复状态。而重复状态则意味着循环。
因为我们假设这一循环不包括位置1,我们设f(i)为循环中某状态,f(0)=1,f(n+1)=(f(n)*2)%(2*N+1),f(j)为若干次循环后出现的重复状态,即f(i)=f(j)。因为循环一直持续,不妨假设j>i+i。又因为循环不包括状态1,即对于任意的k>=i,f(k)!=1
根据定理2.1,我们可以根据当前状态推出上一状态,换句话说,若f(i)=f(j),则f(i-1)=f(j-1)。继续套用定理2.1,可以得到f(i-i)=f(j-i),即:f(j-i)=f(0)=1。又有假设j>i+i,即j-i>i,与另一假设对于任意的k>=i,f(k)!=1矛盾。
因此,可以证明,牌1所陷入的循环,必然是包含位置1的,即一定有某次操作,操作后牌1回到了初始状态。而且显然的,初始状态就是这循环中的一个状态。
因此命题得证。
\.................................................................................................................................................................................................................................................................................................................../
#include<stdio.h>#include <iostream>#include<string.h>#include<stdlib.h>#include<math.h>#include<algorithm>#include<list>#include<vector>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;int main() { int n,i,sum; while(scanf("%d",&n)!=EOF) { sum=1; i=2; while(i!=1) { if(i>n) i=(i-n)*2-1; else i=i*2; sum++; } printf("%d\n",sum); } return 0; }
- hdu 1210 Eddy's 洗牌问题
- HDU 1210 Eddy's 洗牌问题
- HDU 1210 Eddy's 洗牌问题
- HDU 1210 Eddy's 洗牌问题
- hdu 1210 Eddy's 洗牌问题
- HDU 1210 Eddy's 洗牌问题 数论
- hdu-1210-Eddy's 洗牌问题
- hdu 1210 Eddy's 洗牌问题
- hdu 1210 Eddy's 洗牌问题
- hdu---1210Eddy's 洗牌问题
- HDU-1210-Eddy's 洗牌问题
- HDU ACM 1210 Eddy's 洗牌问题
- HDU 1210 Eddy's 洗牌问题
- HDU 1210 Eddy's 洗牌问题
- HDU-1210Eddy's 洗牌问题
- HDU - 1210 Eddy's 洗牌问题
- hdu-1210-Eddy's 洗牌问题
- hdu Eddy's 洗牌问题
- 设置TableView分割线的风格和颜色
- Font-Awesome 魅力四射的html5 css3应用
- Android Studio打不开的问题
- VLAN介绍
- 第4章 memcached的分布式算法
- hdu 1210 Eddy's 洗牌问题
- 巧用异或运算
- 嵌入式学习笔记(4)——51单片机之蜂鸣器和继电器
- Make u-boot-2013.04 on tq2440
- 重建图像的PSNR和MSE的MATLAB实现
- 关于分布式系统的数据一致性问题
- CV牛人事件
- 安卓ndk 中间件编译(初级)
- 关于数据库一些行列转置的问题