2016 Multi-University Training Contest 1 Chess 组合游戏+状压(预处理)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5724
题意:一个n*20的棋盘,n <= 1000;棋盘上有一些棋子,每颗棋子只能移动到右边的第一个空格。不能移动者输;其中 Alice先手;如果Alice能赢输出"YES";
思路:每个子游戏的大小只有20,使用状压即可;但是每个子游戏的SG值需要建立在比其规模更小的SG值之上;这样,在二进制高位变为0低位变为1之后,显然数值变大了;
那么就二进制低位表示高位编码即可;
预处理出所有的有效状态的SG值之后,使用NIM和看ans 是否为0即可;为0表示先手输;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define MSi(a) memset(a,0x3f,sizeof(a)) #define inf 0x3f3f3f3f #define A first #define B second #define MK make_pair #define esp 1e-8 #define zero(x) (((x)>0?(x):-(x))<eps) #define bitnum(a) __builtin_popcount(a) #define clear0 (0xFFFFFFFE) #define mod 1000000007 typedef pair<int,int> PII; typedef long long ll; typedef unsigned long long ull; template<typename T> void read1(T &m) { T x = 0,f = 1;char ch = getchar(); while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); } while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); } m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+'0'); } inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); } int SG[1<<20], state[22]; void init() { for(int i = 0; i < 1<<20; i++){ MS0(state); rep_1(j,19,0){ if(i & (1<<j)){ rep_1(k,j-1,0) if(!(i & (1 << k))){ state[SG[i^(1<<k)^(1<<j)]] = 1; break; } } } rep1(j,0,19) if(state[j] == 0){ SG[i] = j;break; } } } int main() { //freopen("data.txt","r",stdin); //freopen("out.txt","w",stdout); init(); int T, kase = 1; scanf("%d",&T); while(T--){ int n, m, p, ans = 0; read1(n); rep1(i,1,n){ read1(m); int S = 0; while(m--){ read1(p); S |= 1 << 20 - p; } ans ^= SG[S]; } puts(ans?"YES":"NO"); } return 0; }