思路:Fibonacci Nim
枚举前几项,发现2,3,5是必败态,不能说明什么。对于当前的状态,第一次不能全部取完,其余的每次取的时候,不能超过前者上一次的两倍。
对于当前状态n,最多能取的是 ceil(n/3)-1 和 前一状态取的的两倍 两者间的最小值。
然后这里有个齐肯多夫定理:任何一个正整数都可以表示成若干个不连续斐波那契项的和。
若是当前状态时斐波那契项会怎么样,分析一下斐波那契项,F(n)=F(n-1)+F(n-2)=2*F(n-2)+F(n-3)<=2*F(n-2)+F(n-2)-1 所以ceil(F(n)/3)-1 < =F(n-2)-1
如果对手取F(n-2)-1 剩下 F(n)-F(n-2)+1=F(n-1)+1 或者取其他的,都不会让剩下的是非波纳契项。
也就是说,在保证取得数字大小在范围之内的前提下,我们可以控制对手的状态一直是斐波那契项,已知前几项2,3,5是必败态,可以推导一下,发现斐波那契项均是必败态。
对于不是斐波那契数列的,根据齐肯多夫定理,可以表示成若干不连续斐波那契项的和,那么不管对手怎么取,我们要做的就是取若干石子,使剩下的状态呈现为一个非波纳契项。
具体证明请看这里:http://yjq24.blogbus.com/logs/46150651.html
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
using namespace std;
set<int>s;
int main()
{
s.clear();
int x=1,y=1,tmp=x+y;
while(tmp>0)
{
s.insert(tmp);
x=y;
y=tmp;
tmp=x+y;
}
int n;
while(scanf("%d",&n),n)
{
if(s.count(n))
printf("Second win\n");
else
printf("First win\n");
}
return 0;
}