版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gtuif/article/details/82830863
SG函数
结论:游戏和的SG函数等于各个游戏SG函数的Nim和
应用条件:当进行游戏有多种选取方式,可以打sg表或者用dfs得到
例题:
有三堆石子,每堆石子的数量为n,m,k.每次每人可以拿去的石子数量为斐波那契的项的数量,
1、 这是一个二人游戏;
2、 一共有3堆石子,数量分别是m, n, p个;
3、 两人轮流走;
4、 每走一步可以选择任意一堆石子,然后取走f个;
5、 f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
6、 最先取光所有石子的人为胜者;
//f[N]:可改变当前状态的方式,N为方式的种类,f[N]要在getSG之前先预处理
//SG[]:0~n的SG函数值
//S[]:为x后继状态的集合
#include <stdio.h>
#include <string.h>
#define MAXN 1000 + 10
#define N 20
int f[N],SG[MAXN],S[MAXN];
void getSG(int n){
int i,j;
memset(SG,0,sizeof(SG));
for(i = 1; i <= n; i++){
memset(S,0,sizeof(S));
for(j = 0; f[j] <= i && j <= N; j++)
S[SG[i-f[j]]] = 1;
for(j = 0;;j++) if(!S[j]){
SG[i] = j;
break;
}
}
}
int main(){
int n,m,k;
f[0] = f[1] = 1;
for(int i = 2; i <= 16; i++)
f[i] = f[i-1] + f[i-2];
getSG(1000);
while(scanf("%d%d%d",&m,&n,&k),m||n||k){
if(SG[n]^SG[m]^SG[k]) printf("Fibo\n");
else printf("Nacci\n");
}
return 0;
}