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\n"; 26 else cout<<count(n-a[ans])<<endl; 27 } 28 return 0; 29 }
如有转载,请注明出处(http://www.cnblogs.com/lochan)