HDU 1848 —— Fibonacci again and again 【博弈 sg函数】

Fibonacci again and again

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Problem Description

任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:
F(1)=1;
F(2)=2;
F(n)=F(n-1)+F(n-2)(n>=3);
所以,1,2,3,5,8,13……就是菲波那契数列。
在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题。
今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下:
1、  这是一个二人游戏;
2、  一共有3堆石子,数量分别是m, n, p个;
3、  两人轮流走;
4、  每走一步可以选择任意一堆石子,然后取走f个;
5、  f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
6、  最先取光所有石子的人为胜者;

假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢。

Input

输入数据包含多个测试用例,每个测试用例占一行,包含3个整数m,n,p(1<=m,n,p<=1000)。
m=n=p=0则表示输入结束。

Output

如果先手的人能赢,请输出“Fibo”,否则请输出“Nacci”,每个实例的输出占一行。

Sample Input

1 1 1

1 4 1

0 0 0

Sample Output

Fibo

Nacci

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
using namespace std;

int sg[1005];
int f[20];
bool vis[1005];

void Init()
{
    int len=0;
    f[len++] = 1;
    f[len++] = 2;
    while(1) {
        f[len] = f[len-1]+f[len-2];
        if(f[len] > 1000) {
            break;
        }
        len++;
    }

    for(int i=0; i<1003; i++) {
        memset(vis, 0, sizeof(vis));
        for(int j=0; j<len && f[j]<=i; j++) {
            vis[sg[i-f[j]]] = 1;
        }
        for(int j=0; j<=1003; j++) {
            if(!vis[j]) {
                sg[i] = j;
                break;
            }
        }
    }
}

int main ()
{
    Init();
    int m, n, p;
    while(scanf("%d%d%d", &m, &n, &p) != EOF && (m|n|p)) {
        printf("%s\n", sg[m]^sg[n]^sg[p] ? "Fibo":"Nacci");
    }

    return 0;
}
时间: 2024-12-14 18:47:51

HDU 1848 —— Fibonacci again and again 【博弈 sg函数】的相关文章

HDU 1848 Fibonacci again and again【SG函数】

对于Nim博弈,任何奇异局势(a,b,c)都有a^b^c=0. 延伸: 任何奇异局势(a1, a2,… an)都满足 a1^a2^…^an=0 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数. 例如mex{0,1,2,4}=3.mex{2,3,5}=0.mex{}=0. 对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Garundy函数g如下: g(x)=mex{ g(y) | y是x的后继 }. SG函数性

hduoj 1848 Fibonacci again and again【sg函数】【博弈】【菲波那切数列】

Fibonacci again and again Description 任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的: F(1)=1; F(2)=2; F(n)=F(n-1)+F(n-2)(n>=3); 所以,1,2,3,5,8,13--就是菲波那契数列. 在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题. 今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下: 1.  这是

hdu 1848 Fibonacci again and again(简单sg)

Problem Description 任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:F(1)=1;F(2)=2;F(n)=F(n-1)+F(n-2)(n>=3);所以,1,2,3,5,8,13--就是菲波那契数列.在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题.今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下:1.  这是一个二人游戏;2.  一共有3堆石子,数量分别是m

hdu 1848 Fibonacci again and again (SG)

题意: 3堆石头,个数分别是m,n,p. 两个轮流走,每走一步可以选择任意一堆石子,然后取走f个.f只能是菲波那契中的数(即1,2,3,5,8.....) 取光所有石子的人胜. 判断先手胜还是后手胜. 思路: 简单SG.看代码. 代码: int sg[1005]; int dfs(int x){ if(sg[x]!=-1) return sg[x]; bool vis[1005]={0}; int t1=1,t2=2; if(x>=t1) vis[dfs(x-t1)]=true; while(x

HDU - 1848 - Fibonacci again and again

先上题目: Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4964    Accepted Submission(s): 2072 Problem Description 任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:F(1)=1;F

hdu 3032(博弈sg函数)

题意:与原来基本的尼姆博弈不同的是,可以将一堆石子分成两堆石子也算一步操作,其它的都是一样的. 分析:由于石子的堆数和每一堆石子的数量都很大,所以肯定不能用搜索去求sg函数,现在我们只能通过找规律的办法求得sg的规律. 通过打表找规律可以得到如下规律:if(x%4==0) sg[x]=x-1; if(x%4==1||x%4==2) sg[x]=x; if(x%4==3) sg[x] = x+1. 打表代码: #include<iostream> #include<cstdio> #

HDU 3537 Daizhenyang&#39;s Coin(博弈-sg)

Daizhenyang's Coin Problem Description We know that Daizhenyang is chasing a girlfriend. As we all know, whenever you chase a beautiful girl, there'll always be an opponent, or a rival. In order to take one step ahead in this chasing process, Daizhen

UVA 10561 - Treblecross(博弈SG函数)

UVA 10561 - Treblecross 题目链接 题意:给定一个串,上面有'X'和'.',可以在'.'的位置放X,谁先放出3个'X'就赢了,求先手必胜的策略 思路:SG函数,每个串要是上面有一个X,周围的4个位置就是禁区了(放下去必败),所以可以以X分为几个子游戏去求SG函数的异或和进行判断,至于求策略,就是枚举每个位置就可以了 代码: #include <stdio.h> #include <string.h> #include <algorithm> usi

UVA 11534 - Say Goodbye to Tic-Tac-Toe(博弈sg函数)

UVA 11534 - Say Goodbye to Tic-Tac-Toe 题目链接 题意:给定一个序列,轮流放XO,要求不能有连续的XX或OO,最后一个放的人赢,问谁赢 思路:sg函数,每一段...看成一个子游戏,利用记忆化求sg值,记忆化的状态要记录下左边和右边是X还是O即可 代码: #include <stdio.h> #include <string.h> const int N = 105; int t, sg[3][3][N]; char str[N]; int ge

HDU 3032 Nim or not Nim? (sg函数求解)

Nim or not Nim? Problem Description Nim is a two-player mathematic game of strategy in which players take turns removing objects from distinct heaps. On each turn, a player must remove at least one object, and may remove any number of objects provide