HDU-5724-组合博弈

来源:互联网 发布:windows loader win10 编辑:程序博客网 时间:2024/06/18 13:13

题目大意:n行20列的棋盘,对于每行,如果当前棋子右边没棋子,那可以直接放到右边,如果有就跳过放到其后面的第一个空位子,A先操作,最后谁无法操作则输;

题目解析:只有20列,我们通过状态压缩得出序列传入sg函数,写的时候会发现需要把从左往右的序列倒过来,详细看代码;

AC代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>using namespace std;const int N=1<<20; int Hash[21]; int sg[1<<20]; int getSG(int l){      memset(Hash,0,sizeof(Hash));      for(int i=0;i<20;i++)    {    if(l&(1<<i))    {    for(int j=i+1;j<20;j++)    {    if(!(l&(1<<j)))    {    int temp=l;    temp^=((1<<i)^(1<<j));    Hash[sg[temp]]=1;    break;    }    }    }    }    for(int i=0;i<20;i++)    {    if(Hash[i]==0)return i;    }} int n;int main(){memset(sg, 0, sizeof(sg));      for(int i = 0; i < (1 << 20); i++)          sg[i] = getSG(i);  int cas;scanf("%d",&cas);while(cas--){//memset(sg,0,sizeof(sg));int ans=0;scanf("%d",&n);for(int i=0;i<n;i++){int m,t=0;scanf("%d",&m);while(m--){int u;scanf("%d",&u);t|=1<<(u-1);}ans^=getSG(t);}if(ans)printf("YES\n");else printf("NO\n");}return 0;}


原创粉丝点击