HDU2516 - 取石子游戏【斐波那契博弈】

基本描述

有一堆个数为n的石子,游戏双方轮流取石子,满足:

  1. 先手不能再第一次把所有石子取完;
  2. 之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间,包括1和对手取的石子数的2倍。 
    取最后石子的人为赢家。

结论

先说结论: 
当且仅当n不是Fibonacci数时,先手必胜。换句话说,先手必败构成Fibonacci数列。

分析

证明需要前置技能,“Zeckendorf定理”(齐肯多夫定理),其表述为:任何正整数可以表示为若干个不连续的Fibonacci数之和。

具体证明在这篇博文中给出,有兴趣的读者可以自行学习。

例题

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
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
int main()
{
    int fib[60];
    fib[0]=fib[1]=1;
    for(int i=2;i<=55;++i)
        fib[i]=fib[i-1]+fib[i-2];
    int n;
    while(scanf("%d",&n)!=EOF && n)
    {
        bool flag=true;
        for(int i=0;i<=55;++i)
        {
            if(fib[i]==n)
            {
                flag=false;
                break;
            }
        }
        if(flag)
            printf("First win\n");
        else
            printf("Second win\n");
    }
    return 0;
}

 

posted @ 2018-08-16 19:27  浮生惘语  阅读(180)  评论(0编辑  收藏  举报