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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章