ZOJ2290_Game

题目意思是这样的,给定一个数N,第一个可以减去任意一个数(不能为N本身),然后接下来轮流减去一个数字,下一个人减去的数字必须大于0,且不大于2倍上一次被减去的数字。

把N减为0的人获胜。

看完题目后不会做,果断就上午找题解了。

原来如此啊。。。。 首先我们可以打个表(在30的范围以内),就可以发现必败态是N为斐波那契数。

也就是说如果给定的数字不是一个斐波那契额数,那么就是必胜的。

接下来的问题是如何找到一个第一次减小的最小的数字呢?

可以递归找,每次都找最近的,知道恰好等于一个斐波那契数为止。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #define inf (unsigned)(~0U)
 5 using namespace std;
 6 
 7 unsigned a[50],n,ans;
 8 
 9 unsigned count(unsigned x)
10 {
11     int k=0;
12     for (; a[k+1]<=x && k<=45; k++);
13     if (a[k]==x) return x;
14     else return count(x-a[k]);
15 }
16 
17 int main()
18 {
19     a[1]=1;a[2]=2;a[3]=3;
20     for (unsigned k=2; inf-a[k]>=a[k-1]; k++) a[k+1]=a[k]+a[k-1];
22     while (cin>>n)
23     {
24         for (ans=1; a[ans+1]<=n && ans<=45; ans++);
25         if (n==a[ans]) cout<<"lose
";
26             else cout<<count(n-a[ans])<<endl;
27     }
28     return 0;
29 }
如有转载,请注明出处(http://www.cnblogs.com/lochan)
原文地址:https://www.cnblogs.com/lochan/p/3375097.html