HDU 2516 取石子游戏(斐波那契博弈)

取石子游戏(传送门)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
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

此题需要用到一个结论:“Zeckendorf定理”(齐肯多夫定理):任何正整数可以表示为若干个不连续的Fibonacci数之和。
分析:
n = 2时输出second;
n = 3时也是输出second;
n = 4时,第一个人想获胜就必须先拿1个,这时剩余的石子数为3,此时无论第二个人如何取,第一个人都能赢,输出first;
n = 5时,first不可能获胜,因为他取2时,second直接取掉剩下的3个就会获胜,当他取1时,这样就变成了n为4的情形,所以输出的是second;
n = 6时,first只要去掉1个,就可以让局势变成n为5的情形,所以输出的是first;
n = 7时,first取掉2个,局势变成n为5的情形,故first赢,所以输出的是first;
n = 8时,当first取1的时候,局势变为7的情形,第二个人可赢,first取2的时候,局势变成n为6得到情形,也是第二个人赢,取3的时候,second直接取掉剩下的5个,所以n = 8时,输出的是second;
…………
从上面的分析可以看出,n为2、3、5、8时,这些都是输出second,即必败点,仔细的人会发现这些满足斐波那契数的规律,可以推断13也是一个必败点。
参考:
https://www.cnblogs.com/SuBlog/archive/2012/08/26/2657710.html
严格的数学证明可参考:
https://blog.csdn.net/dgq8211/article/details/7602807

#include
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int fib[50] = {2,3};
    for(int i = 2; i < 45; i++)
        fib[i] = fib[i - 1] + fib[i - 2];
    int n;
    while(cin>>n && n)
    {
        int flag = 1;
        for(int i = 0; i < 44; i++)
        if(fib[i] == n){
            flag = 0;
            break;
        }
        if(flag)cout<<"First win"<else cout<<"Second win"<return 0;
}

你可能感兴趣的:(HDU,博弈)