http://acm.hust.edu.cn/vjudge/contest/view.action?cid=108499#overview
题目分类:
sg函数:A,E,H,I
尼姆博弈:B,C,
巴氏博弈:D,F
np点性质或总结规律:G
A.题意:每组测试用例包含三个整数m,n,p.以n,m,p都为零结束。表示三堆石子,每堆石子的个数。每步取走石子个数满足斐波那契数列(从1开始的)判断先手赢还是后手赢。
分析:直接利用sg函数,注意要生成每步可以取走石子的个数
代码:
dfs递归版本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <climits>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <cctype>
typedef long long ll;
const int MOD=10e9+7;
const int INF=0x7fffffff;
const double ESP=10e-7;
const double Pi=acos(-1.0);
const int dr[]= {0,0,1,-1,1,1,-1,-1};
const int dc[]= {-1,1,0,0,-1,1,-1,1};
using namespace std;
const int MAXN=1005;
//bool vis[MAXN];
int a[MAXN],sg[MAXN];
void init()
{
a[1] = 1,a[2] = 2;
for(int i = 3; i < 20; i ++)
{
a[i] = a[i - 1] + a[i - 2];
// cout<<a[i]<<endl;
}
}/*
int SG(int now){
int i,tem;
int next[20];
memset(next,0,sizeof(next));
for(i=1;a[i]<=now;i++){
tem=now-a[i];
if(sg[tem]==-1)
sg[tem]=SG(tem);
next[sg[tem]]=1;
}
for(i=0;;i++)
if(next[i]==0){
return i;
}
}*/
int SG(int x)
{
bool vis[25];
memset(vis,false,sizeof(vis));
int temp;
for(int i = 1;a[i] <= x ; i ++)
{
//cout<<a[i]<<endl;
temp = x - a[i];
if(sg[temp] == -1)
{
sg[temp] = SG(temp);
}
vis[sg[temp]] = true;
}
for(int i = 0;; i ++)
{
if(vis[i] == false)
{
return i;
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
int m,n,p;
init();
while(scanf("%d%d%d",&m,&n,&p))
{
memset(sg,-1,sizeof(sg));
if(n == 0 && m == 0 && p == 0)
break;
// cout<<SG(m)<<SG(n)<<SG(p)<<endl;
if((SG(n) ^ SG(m) ^ SG(p)) != 0)
printf("Fibo\n");
else
printf("Nacci\n");
}
return 0;
}
//打表版
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <climits>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <cctype>
typedef long long ll;
const int MOD=10e9+7;
const int INF=0x7fffffff;
const double ESP=10e-7;
const double Pi=acos(-1.0);
const int dr[]= {0,0,1,-1,1,1,-1,-1};
const int dc[]= {-1,1,0,0,-1,1,-1,1};
using namespace std;
const int MAXN=1005;
//bool vis[MAXN];
int a[MAXN],sg[MAXN];
void init()
{
a[1] = 1,a[2] = 2;
for(int i = 3; i < 20; i ++)
{
a[i] = a[i - 1] + a[i - 2];
// cout<<a[i]<<endl;
}
}
int b[MAXN];
void SG()
{
memset(sg,0,sizeof(sg));
for(int i = 1; i <= 1000; i ++)
{
memset(b,true,sizeof(b));
for(int j = 1; j < 16; j ++)
{
if(i < a[j])
break;
b[sg[i - a[j]]] = false;//不是i - a[j]是sg[i-a[j]]
}
for(int j = 0; j <= 1000; j +&#