HDU1848 Fibonacci again and again 题解 SG函数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1848

题目大意:

  1. 这是一个二人游戏;
  2. 一共有3堆石子,数量分别是m, n, p个;
  3. 两人轮流走;
  4. 每走一步可以选择任意一堆石子,然后取走f个;
  5. f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
  6. 最先取光所有石子的人为胜者;

问谁赢?

解题思路:

求 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;
}
posted @ 2020-12-02 19:13  quanjun  阅读(114)  评论(0编辑  收藏  举报