前言
一道斐波那契博弈的题目,SG函数理解有点困难,这个类型又很有特点,于是记录一下。
HDU-2516 取石子游戏
题目描述:
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是斐波那契数,那么先手必输,如果不是,先手必胜。
代码里用到了斐波那契数列的通项公式来处理数据
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <stdio.h> #include <math.h> int main(){ float n; int kase = 0; scanf("%f", &n); while(n != 0){ for(int i = 0;i < 50; i++){ float a = (1/sqrt(5))*(pow((1+sqrt(5))/2,i)-pow((1-sqrt(5))/2,i)); if(n == a){ printf("Second win\n"); kase = 1; break; } } if(!kase) printf("First win\n"); kase = 0; scanf("%f", &n); } return 0; } |
总结
关于这个博弈的证明有些复杂,于是干脆当成结论记下来吧。