2016 多校最后一题 (HDU 5724) Chess (组合博弈)

来源:互联网 发布:什么软件看小说免费 编辑:程序博客网 时间:2024/05/23 16:55

题目大概说有n行,每行20格子,都有一些棋子,两个人轮流进行这个操作:选择某一行一个棋子移动到该行右边第一个空的格子。不能进行的人输。问先手是否能赢。

这个博弈显然是组合博弈,先手后手交替进行、每次决策是有限的、有胜利条件。。然后SG定理搞了。。用set记录集合竟然T了。。。。

#include <cstdio>#include <iostream>#include <set>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 2000010#define MOD 1000000007int n,m;int sg[maxn];int main(){    int t;    sg[0] = 0;    sg[1] = 0;    for(int x = 2; x <= (1<<20); x++)    {        int h[25] = {0};        int pre = -1;        for(int i = 0; i <= 20; i++)        {            if(x&(1<<i))            {                if(pre == -1)                    continue;                else                {                    int k = x - (1<<i) + (1<<pre);                    h[sg[k]] = 1;                }            }            else                pre = i;        }        int res = 0;        while(h[res])            res++;        sg[x] = res;    }    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        int ans = 0;        for(int i = 0; i < n; i++)        {            scanf("%d",&m);            int k = 0;            for(int j = 0; j < m; j++)            {                int x;                scanf("%d",&x);                k += (1<<(20-x));            }            ans ^= sg[k];        }        printf("%s\n",ans==0?"NO":"YES");    }    return 0;}


0 0