求助博弈SG函数
查看原帖
求助博弈SG函数
540979
流泪的小酒窝楼主2023/10/5 16:36

正常SG函数为转移的 mexmex
但是如果我们只能求出他是必胜态还是必败态,异或起来是对的吗?(按照这个思路写了一个,喜提20pts,想知道为啥挂了)

#include<bits/stdc++.h>
using namespace std;
const int N=20;
int f[1<<20|1];//0输1赢
int hv[N+1];
void gt(int x) {
	for(int i=19; i>=0; i--)
		printf("%d",(x>>i)&1);
	printf(" %s\n",f[x]?"WIN":"LOSS");
}
int main() {
//	freopen("out.out","w",stdout);
	for(int i=0; i<1<<20; i++) {
		memset(hv,0,sizeof(hv));
		int lst=-1,sum=0;
		for(int j=0; j<20; j++) {
			if((i>>j)&1) {
				hv[20-j]=1;
				sum++;
				if(lst==-1)continue;
				else if(!f[i^(1<<j)^(1<<lst)])f[i]=1;
			} else lst=j;
		}
		int cnt=20-sum+1,ans1=0,tot=0;
		for(int i=1; i<=20; ++i) {
			if(!hv[i]) {
				if((--cnt)&1)ans1^=tot;//奇数级阶梯,异或
				tot=0;
			} else ++tot; //加棋子到阶梯上
		}
//		if(i==6){
//			puts("have:");
//			for(int j=1;j<=20;j++)printf("%d ",hv[j]);puts("");
//		}
////		gt(i);
//		if((ans1>0&&f[i]==0)||(ans1==0&&f[i]>0)){
//			printf("%d ans1:%d",i,ans1);
//			return 0;
//		}
	}
	int T;
	scanf("%d",&T);
	while(T--) {
		int n,res=0;
		scanf("%d",&n);
		for(int i=1; i<=n; i++) {
			int t=0,m,x;
			scanf("%d",&m);
			for(int j=1; j<=m; j++) {
				scanf("%d",&x);
				t|=1<<20-x;
			}
			res^=f[t];
		}
		if(res)puts("YES");
		else puts("NO");
	}
}

/*
左 001101001 右
*/
2023/10/5 16:36
加载中...