sg 函数

sg 同时被 2 个专栏收录
1 篇文章 0 订阅
6 篇文章 0 订阅

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;
    }
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值