zoukankan      html  css  js  c++  java
  • ZOJ 3666 博弈 SG函数

    SG函数:

    对于任意状态,定义SG(x)=mex(S),其中S是x的后继状态的SG函数值集合,mex(S)表示不再S内的最小非负整数

    SG(X)=0当且仅当x为必败态。

    解:

    构造一个有向无环图(树),SG(x)=mex(SG(y)) y为x的孩子节点。

    SG(所有叶子节点)=0

    #include <stdio.h> 
    #include <algorithm>
    #include <string.h>
    #include <vector>
    using namespace std;
    #define MAXN    10005
    int n;
    int sg[MAXN]; 
    vector <int >map[MAXN];
    int vis[MAXN];
    void dfs(int y)
    {
        if (vis[y]) return;
        int i,j;
        int x;
        vector<int> tmp;
            for (j=0;j<map[y].size();j++)
            {
                dfs(map[y][j]);
                tmp.push_back(sg[map[y][j]]);
            }
            sort(tmp.begin(),tmp.end());
            x=0;
            int flag=true;
            for (i=0;i<tmp.size();i++)
                if (tmp[i]==x)
                    x++;
                else
                {
                    if (tmp[i]>x)
                    {
                        break;
                    }
                }
            sg[y]=x;
            vis[y]=1;
    }
    int main() 
    {    
        int i,j,m,x;
        int dot[MAXN];
        int cas=1;
        while (scanf("%d",&n)!=EOF)
        {
            printf("Case %d:
    ",cas++);
            for (i=1;i<=n;i++)
                map[i].clear();
            memset(sg,0,sizeof(sg));
            memset(vis,0,sizeof(vis));
            for (i=1;i<n;i++)
            {
                scanf("%d",&dot[i]);
                for (j=0;j<dot[i];j++)
                {
                    scanf("%d",&x);
                    map[i].push_back(x);
                }
            }
            sg[n]=0;
            for (i=1;i<=n;i++)
                if (!vis[i])
                    dfs(i);
            int q;
            int p;
            scanf("%d",&q);
            for (i=0;i<q;i++)
            {
                scanf("%d",&p);
                int ans=0;
                for (j=0;j<p;j++)
                {
                    scanf("%d",&x);
                    ans^=sg[x];
                }
                if (ans==0)
                    printf("Bob
    ");
                else
                    printf("Alice
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    一个C# usb与mcu通信的程序,附代码
    基于C#音乐播放器(附代码)
    基于C#俄罗斯方块
    FTP方式部署Azure Web App
    微信接口小例
    基于来信码的短信通知平台
    基于Windows服务的WCF
    基于IIS的WCF
    基于.NET的Excel开发:单元格区域的操作(读取、赋值、边框和格式)
    .NET通过RFC读取SAP数据
  • 原文地址:https://www.cnblogs.com/six-god/p/3748829.html
Copyright © 2011-2022 走看看