sg 函數

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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章