博弈专题 sg函数子状态+链涂色

题目链接:https://vjudge.net/contest/299140#problem/J
题目大意:一个圆环N个珠子,每次每个人只能给连续的M个数珠子涂色,最后不能涂的就算输。

每次涂色后相当于把链分成没有涂色的两部分



根据sg定理:当前状态的SG函数等于各个子状态SG函数的异或和
所以枚举所有的子状态就可以了。

#include <bits/stdc++.h>
#define LL long long
using namespace std;

int sg[1010]={0};
int n, m;
int  get_sg(int len)
{
    if(len<m)//长度<m无法涂色
    {
        return 0;
    }
    if(sg[len]!=-1)
    {
        return sg[len];
    }
    bool vis[1010]={0};
    for(int i=0;i+m<=len;i++)
    {
        vis[get_sg(i)^get_sg(len-m-i)]=true;
    }
    for(int i=0;i<=len;i++)//mex
    {
        if(!vis[i])
        {
            return sg[len]=i;
        }
    }
}

int main()
{
    int T, CUT=0;
    scanf("%d",&T);
    while(T--)
    {
        CUT++;
        scanf("%d %d",&n,&m);
        printf("Case #%d: ",CUT);
        if(m==1)
        {
            if(n&1)
            {
                printf("aekdycoin\n");
            }
            else
            {
                printf("abcdxyzk\n");
            }
            continue;
        }
        memset(sg, -1, sizeof(sg));
        sg[0]=0;
        if(n>=m&&!get_sg(n-m))
        {
            printf("aekdycoin\n");
        }
        else
        {
            printf("abcdxyzk\n");
        }

    }

    return 0;
}

全部评论

相关推荐

头像
10-09 19:35
门头沟学院 Java
洛必不可达:java的竞争激烈程度是其他任何岗位的10到20倍
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务