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
这是一道斐波那契博弈的裸题,这个题目的结论就是如果输入的这个n是斐波那契数的话就先手必败,否则就先手必胜
下面让我们一起讨论一下斐波那契博弈
首先我们引入齐肯多夫定理:任何正整数都可以表示成若干个不连续的斐波那契数(不包括第一个斐波那契数)之和。
我们自底向上开始一步步推来寻找答案
n = 2时不管怎么后手必胜
n = 3时同样不管怎么走后手必胜
n = 4时,第一个人想获胜就必须先拿1个,这时剩余的石子数为3,此时无论第二个人如何取,第一个人都能赢,先手必胜;
n = 5时,先手不可能获胜,因为先手取2时,后手直接取掉剩下的3个就会获胜,当先手取1时,这样就变成了n为4的情形,所以还是后手胜;
n = 6时,先手只要去掉1个,就可以让局势变成n为5的情形,所以还是后手必胜;
n = 7时,先手取掉2个,局势变成n为5的情形,故后手必胜;
n = 8时,当先手取1的时候,局势变为7的情形,后手胜,先手取2的时候,局势变成n为6得到情形,后首胜,取3的时候,后手直接取掉剩下的5个,所以n = 8时,所以还是后首胜;
……
我们发现当n=2,3,5,8的时候后手胜,所以我们推断当这个数是斐波那契数的时候后手必胜,推断下一次后首胜的时候是n等于13,我们进行验证果然n=13后手胜,这时候主卧室一种猜测,怎么证明这种猜测呢,我们就需要看齐肯多夫定理了。这个定理也佐证了我们的结论
下面附上AC代码
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
ll a[100];
void Fib()
{
a[1]=1;
a[2]=1;
for(ll i=3;i<50;i++)
{
a[i]=a[i-1]+a[i-2];
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
ll n;
Fib();
while(cin>>n&&n!=0)
{
ll flag=0;
for(ll i=1;i<50;i++)
{
if(n==a[i])
{
cout<<"Second win"<<endl;
flag=1;
break;
}
}
if(flag==0)
cout<<"First win"<<endl;
}
return 0;
}