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;
}
原文地址:https://www.cnblogs.com/tom987690183/p/3099717.html