HDU 2516 取石子游戏
http://acm.hdu.edu.cn/showproblem.php?pid=2516
取石子游戏
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1806 Accepted Submission(s): 1027
Problem Description
1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜.先取者负输出"Second win".先取者胜输出"First win".
Input
输入有多组.每组第1行是2<=n<2^31. n=0退出.
Output
先取者负输出"Second win". 先取者胜输出"First win". 参看Sample Output.
Sample Input
2
13
10000
0
Sample Output
Second win
Second win
First win
Source
Recommend
刚刚看到这个的时候,觉得没什么思路的。后来发现和省赛以前的一题博弈很像。
刚开始的时候是列出了情况
2 lost
3 lost
4 win
5 lost 因为此时取值无法使对方处于 lost状态。
6 win
7 win
8 lost 因为此时无法使得对方 处于lost 状态。
9win
10 win
11 win
12 lost 同理。根据了一次性取值,无法使得对方处于 最靠近的lost 8 ,而使得对方胜,自己输了。所以lost。
然而问题也就在这里出现。 我们只是想一次性就让对方处于lost状体,也就是说,不能给对方win的机会。其实不是的,我们只要最后是win就可以了,
在中间过程中运行出现win状态,但是由于2倍个数的限制,使其无法给我们lost状态度。因为
对于12,我们可以先去1,(给对方win) 对方无可奈何,只能取1或者2,但是我们都会处于win状态。然后取到8.ok,我们赢了。
将前几次组的lost列出来看一看,2 . 3 . 5 . 8 .13 菲波数啊。
但是具体的理论证明,还没有.............................额额。
#include<stdio.h> #include<math.h> __int64 f[61]; void dabiao() { __int64 i; f[0]=2; f[1]=3; for(i=2;i<=60;i++) f[i]=f[i-1]+f[i-2]; } int main() { __int64 i,n,m; dabiao(); while(scanf("%I64d",&n)>0) { if(n==0)break; m=0; for(i=0;i<=60;i++) if(f[i]>0) if(f[i]==n) { m=1; break; } if(m==0) printf("First win\n"); else if(m==1) printf("Second win\n"); } return 0; }