hdu 1848 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函数的应用。自己也是看了百度文库的解题报告才写出来的,对sg函数的应用还要继续学习啊。。。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int e[1005]={0,1,2,3};
int b[16],f[1005]={0,1,2,3};  //b 记录有木有出现过。
void feibo(){
    for(int i=4;i<1005;i++){
         f[i]=f[i-1]+f[i-2];
    }
}
void E(){
    for(int i=4;i<=1000;i++)
	{
	  for(int j=0;j<=15;j++)  b[j]=0;
	  for(int j=1;f[j]<=i;j++)   b[e[i-f[j]]]=1;  //出现就设为1
	  for(int j=0;j<=15;j++)   if(b[j]==0){e[i]=j;break;}
	}
}
int main()
{
    //freopen("cin.txt","r",stdin);
    int m,n,p;
    feibo();
    E();
    while(cin>>m>>n>>p){
	   if(m==0&&n==0&&p==0)break;
	   if((e[m]^e[n]^e[p])==0)cout<<"Nacci"<<endl;
	   else cout<<"Fibo"<<endl;
    }
    return 0;
}



你可能感兴趣的:(HDU)