当前位置: 代码迷 >> 综合 >> Hdu 2516 取石子游戏 【斐波那契博弈】
  详细解决方案

Hdu 2516 取石子游戏 【斐波那契博弈】

热度:92   发布时间:2023-11-11 11:37:12.0

取石子游戏

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5147    Accepted Submission(s): 3108


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

Source
ECJTU 2008 Autumn Contest

Recommend
lcy

斐波那契博弈模板:堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜

思路:
n = 2时输出second;     
 n = 3时也是输出second;
 n = 4时,第一个人想获胜就必须先拿1个,这时剩余的石子数为3,此时无论第二个人如何取,第一个人都能赢,输出first;
 n = 5时,first不可能获胜,因为他取2时,second直接取掉剩下的3个就会获胜,当他取1时,这样就变成了n为4的情形,所以输出的是second;   
 n = 6时,first只要去掉1个,就可以让局势变成n为5的情形,所以输出的是first;      
 n = 7时,first取掉2个,局势变成n为5的情形,故first赢,所以输出的是first;     
 n = 8时,当first取1的时候,局势变为7的情形,第二个人可赢,first取2的时候,局势变成n为6得到情形,也是第二个人赢,取3的时候,second直接取掉剩下的5个,所以n = 8时,输出的是second;
从上面的分析可以看出,n为2、3、5、8时,这些都是输出second,即必败点,仔细的人会发现这些满足斐波那契数的规律,可以推断13也是一个必败点。     
 所以我们可以利用斐波那契数的公式:fib[i] = fib[i-1] + fib[i-2],只要n是斐波那契数就输出second
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{int fib[50];fib[0]=0;fib[1]=1;for(int i=2; i<48; i++)///再开大的话就爆了{fib[i]=fib[i-1]+fib[i-2];}int n;while(~scanf("%d",&n)){if(n==0){break;}int flag=1;for(int i=2; i<=48; i++){if(n==fib[i]){printf("Second win\n");flag=0;break;}}if(flag){printf("First win\n");}}return 0;}