poj 2425 A Chess Game (SG函数)

版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/83780442

题目链接:poj 2425

题意:题目会给出一个有向无环图,对于某个棋子,可以将它移动到其后继棋子的任意一个位置,一个位置可以放多个棋子。

给出n个点,从0到n-1,接着n行,每行开始有Xi,代表第i个点后继连接点有Xi个,分别是......。

紧接着有多组询问,每组询问的M代表有哪几个可走的棋子(M为0时询问结束),问:谁能获胜?先走获胜输出 WIN。

题解:就是个SG函数。

参考博客:https://blog.csdn.net/i1020/article/details/79395763

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>

using namespace std;

const int maxn=1010;

vector<int> que[maxn];

int SG[maxn];


int dfs(int x)
{
    if(SG[x]!=-1) return SG[x];
    
    bool vis[maxn]; ///这里不应放在函数外,因为每次递归调用都需用这个标记函数
    ///假设放在函数外,会产生混乱,注意下这个大坑
    memset(vis,0,sizeof(vis));

    for(int i=0;i<que[x].size();i++)
    {
        dfs(que[x][i]);
        vis[SG[que[x][i]]]=1;
    }

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

    return SG[x];
}
int main()
{

    int n;
    int item,num;
    while(~scanf("%d",&n))
    {


        for(int i=0;i<n;i++)
        {
            que[i].clear();
            scanf("%d",&num);

            while(num--)
            {
                scanf("%d",&item);
                que[i].push_back(item);
            }
        }

        memset(SG,-1,sizeof(SG));

        for(int i=0;i<n;i++)
            SG[i]=dfs(i);

        while(~scanf("%d",&num)&&num)
        {
            int sum=0;
            while(num--)
            {
                scanf("%d",&item);
                sum^=SG[item];
            }

            if(sum) printf("WIN\n");
            else printf("LOSE\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LJD201724114126/article/details/83780442