新年第一发--HDU1848--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, 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

Author

lcy

Source

ACM Short Term Exam_2007/12/13

Recommend

lcy

思路:

这是一道SG函数的裸题,用到了SG函数的和(多堆石子的Nim游戏)

 

我们可以定义有向图游戏的和(Sum of Graph Games):

设G1、G2、……、Gn是n个有向图游戏,定义游戏G是G1、G2、……、Gn的和,游戏G的移动规则是:任选一个子游戏Gi并移动上面的棋子。

Sprague-Grundy Theorem:g(G)=g(G1)^g(G2)^...^g(Gn)。也就是说,游戏的和的SG函数值是它的所有子游戏的SG函数值的异或。

 

这里,每一堆石子都可以看作一个有向图游戏,它们的和即为整个大游戏,所以,运用Sprague-Grundy Theorem即可

这篇博客写的很好:

http://www.cnitblog.com/weiweibbs/articles/42735.html

 

代码:

#include<bits/stdc++.h>
using namespace std;
int f[19];
int sg[1050];
bool tmp[19];
int m,n,p;
int N;
void fi()
{
    f[0]=1;f[1]=2;
    for(int i=2;i<19;i++){
        f[i]=f[i-1]+f[i-2];
    }
}
void s()
{
    fi();
    sg[0]=0;
    for(int i=1;i<N;i++){
        memset(tmp,0,sizeof(tmp));
        for(int j=0;f[j]<=i;j++){
            tmp[sg[i-f[j]]]=1;
        }
        for(int j=0;j<19;j++){
            if(!tmp[j]){
                sg[i]=j;
                break;
            }
        }
    }
}
int main()
{
    N=1000;
    s();
    while(cin>>m>>n>>p){
        if(m==0&&n==0&&p==0)
            break;
        if(sg[m]^sg[n]^sg[p]){
            cout<<"Fibo"<<endl;
        }
        else cout<<"Nacci"<<endl;
    }
}

新年第一发,我要来开光~~~~~~

//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0  =  /0
//                    ___/`---'\___
//                  .' \|     |// '.
//                 / \|||  :  |||// 
//                / _||||| -:- |||||- 
//               |   | \  -  /// |   |
//               | \_|  ''---/''  |_/ |
//                 .-\__  '-'  ___/-. /
//             ___'. .'  /--.--  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;` _ /`;.`/ - ` : | |
//            `_.   \_ __ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//
//
新的一年,加油!