#Multi-SG#BZOJ 2940 [POI2000] 条纹

题目

\(n\)个格子,可以选择三种长度的线段覆盖,不能重叠,
无法覆盖者为负,问先手是否必胜,\(n\leq 10^3\)


分析

考虑选择一个位置覆盖则该局面分成两个局面,
直接求出SG函数不为0先手必胜即可


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
int n,m,k,v[1001],sg[1001];
inline signed iut(){
	rr int ans=0,f=1; rr char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans*f;
}
signed main(){
	n=iut(),m=iut(),k=iut();
	for (rr int i=1;i<1001;++i){
		for (rr int j=0;j+n<=i;++j)
		    v[sg[j]^sg[i-j-n]]=1;
		for (rr int j=0;j+m<=i;++j)
		    v[sg[j]^sg[i-j-m]]=1;
        for (rr int j=0;j+k<=i;++j)
		    v[sg[j]^sg[i-j-k]]=1;
		for (;v[sg[i]];++sg[i]);
		for (rr int j=0;j+n<=i;++j)
		    v[sg[j]^sg[i-j-n]]=0;
		for (rr int j=0;j+m<=i;++j)
		    v[sg[j]^sg[i-j-m]]=0;
        for (rr int j=0;j+k<=i;++j)
		    v[sg[j]^sg[i-j-k]]=0;
	}
	for (rr int T=iut();T;--T)
	    putchar(sg[iut()]?49:50),putchar(10);
	return 0;
}
posted @ 2021-04-06 11:44  lemondinosaur  阅读(26)  评论(0编辑  收藏  举报