题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1848
题目大意:
- 这是一个二人游戏;
- 一共有3堆石子,数量分别是m, n, p个;
- 两人轮流走;
- 每走一步可以选择任意一堆石子,然后取走f个;
- f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
- 最先取光所有石子的人为胜者;
问谁赢?
解题思路:
求 SG 函数,然后异或。
示例代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1001;
int sg[maxn], f[maxn], cnt, m, n, p;
bool vis[maxn];
int main() {
f[0] = f[1] = 1;
for (cnt = 1; f[cnt] < maxn; cnt ++) f[cnt+1] = f[cnt-1] + f[cnt];
for (int i = 1; i < maxn; i ++) {
memset(vis, 0, sizeof(vis));
for (int j = 1; f[j] <= i; j ++)
vis[sg[i-f[j]]] = true;
for (int j = 0; vis[j]; sg[i] = ++j);
}
while (~scanf("%d%d%d", &m, &n, &p) && m+n+p)
puts(sg[m] ^ sg[n] ^ sg[p] ? "Fibo" : "Nacci");
return 0;
}