一.题目链接:
HDU-1848
二.题目大意:
有三堆石子,石子个数分别为 m, n, p
两个人玩游戏,规则如下:
两个人轮流取石子,每次选择一堆石子,取的个数必须为斐波那契数列的项
最先取光所有石子的人获胜.
三.分析:
没啥好分析的,就是一道 SG 函数水题.
附上博弈学习的链接
转载 - 1
转载 - 2
四.代码实现:
#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <ctime>
#define eps 1e-6
#define pi acos(-1.0)
#define ll long long int
using namespace std;
const int M = 1000;
int fib[20];
int sg[M + 5];
bool vis[M + 5];
void init()
{
fib[1] = 1;
fib[2] = 1;
for(int i = 3; ; ++i)
{
fib[i] = fib[i - 1] + fib[i - 2];
if(fib[i] > M)
break;
}
memset(sg, 0, sizeof(sg));
for(int i = 1; i <= M; ++i)
{
memset(vis, 0, sizeof(vis));
for(int j = 1; fib[j] <= i && fib[j] <= M; ++j)
vis[sg[i - fib[j]]] = 1;
for(int j = 0; ; ++j)
{
if(!vis[j])
{
sg[i] = j;
break;
}
}
}
}
int main()
{
init();
int m, n, p;
while(~scanf("%d %d %d", &m, &n, &p))
{
if(m + n + p == 0)
break;
if(sg[n] ^ sg[m] ^ sg[p])
printf("Fibo\n");
else
printf("Nacci\n");
}
return 0;
}