尼姆博弈的SG值计算简单模板

#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 111

int sg[111];
int get_sg(int s){ // 记忆化搜索

    if(sg[s]!=-1) return sg[s]; // 不为-1,说明s的sg值已经被计算了,记忆化搜索不用再搜索计算了,直接返回已经算出来的结果

    bool vis[MAXN]={0}; // 标记各个数是否被访问过,用于实现mex运算

    for(int i=1; i<=s; ++i){ // 枚举取几个石子,转移到下一个局面
        vis[get_sg(s-i)]=1; // 标记下一个局面s-i的sg值
    }

    for(int i=0; ; ++i){ // 找到最小的没有被标记的非负整数,就是mex运算的实现
        if(!vis[i]){ // 没有被标记
            return sg[s]=i; // 当前局面的s的sg值就等于最小的没有被标记的sg值
        }
    }
}

void get_sg(){ // 从小到大枚举,依次计算SG值
    // 同上
    for(int s=0; s<MAXN; ++s){

        bool vis[MAXN]={0};

        for(int i=1; i<=s; ++i){
            vis[sg[s-i]]=1;
        }

        for(int i=0; ; ++i){
            if(!vis[i]){
                sg[s]=i;
                break;
            }
        }
    }
}

int main(){

    memset(sg,-1,sizeof(sg));
    for(int i=0; i<MAXN; ++i){
        printf("%d ",get_sg(i));
    }

    puts("\n");

    get_sg();
    for(int i=0; i<MAXN; ++i){
        printf("%d ",get_sg(i));
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章