HDU 5724/2016多校1B Chess

来源:互联网 发布:暗影格斗2mac版修改 编辑:程序博客网 时间:2024/06/03 22:47

题意:一个博弈中,n行20列的棋盘,给出每行棋子分布,每次可以将一个棋子移至其右侧最近的空位,求先手输赢。

题解:推了快一个小时的规律,结果发现有毛线规律啊,数据这么小,暴力不就好了嘛...对于某一个状态dfs搜他的子状态,求出每个位置的sg函数,n行的sg值异或起来就是答案了

#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<vector>#include<list>#include<set>#include<map>#include<stack>#include<queue>#include<deque>#define mem(x,y) memset(x,y,sizeof(x))#define pb push_backusing namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,double> pii;#define bug puts("===========");#define zjc puts("");const double pi=(acos(-1.0));const double eps=1e-8;const ll INF=1e18+10;const ll inf=1e9+10;const int mod=1e9+7;const int maxn=100000+10;int sg[1<<23];int getsg(int x){    if(sg[x]!=-1) return sg[x];    int kong=0;    bool vis[25];    mem(vis,0);    for(int i=1;i<=20;i++){        if(x&(1<<i)){            if(!kong) continue;            vis[getsg(x-(1<<i)+(1<<kong))]=1;        }        else kong=i;    }    for(int i=0;i<=20;i++) if(vis[i]==0) return sg[x]=i;}int main(){    int T_T;    mem(sg,-1);    sg[0]=0;    scanf("%d",&T_T);    while(T_T--){        int n,ans=0;        scanf("%d",&n);        for(int i=1;i<=n;i++){            int m,zt=0,a;            scanf("%d",&m);            for(int j=0;j<m;j++){                scanf("%d",&a);                zt|=1<<(20-a+1);            }            ans^=getsg(zt);        }        if(ans==0) puts("NO");        else puts("YES");    }    return 0;}


0 0
原创粉丝点击