题意为:N*20的棋盘,刚开始有一些棋子在上面,棋子只能向前移动,不能向下或向上移动。如果该棋子前面有棋子,则可以跳过前面的棋子移动到下一个空位,但是并不能跳过空位,来移动到下一个空位。最后,谁不能移动棋子谁就输。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#define MAXN 200010
using namespace std;
int sg[1<<21];
int met[22];
int DFS(int temp){
if(sg[temp] != -1){
return sg[temp];
}
memset(met,0,sizeof(met));
for(int i = 0; i < 20; i++){
if(temp & (1<<i)){
int t = temp;
for(int j = i+1; j < 20; j++){
if(temp & (1<<j)){
continue;
}
t ^= ((1<<i)^(1<<j));
met[sg[t]] = 1;
break;
}
}
}
for(int i = 0; i <= 20; i++)
{
if(met[i] == 0){
sg[temp] = i;
return i;
}
}
return 0;
}
void init(){
memset(sg,-1,sizeof(sg));
for(int i = (1<<20)-1; i >= 0; i--){
sg[i] = DFS(i);
}
}
int main(){
int T;
int n,m;
int x,ans,sum;
init();
scanf("%d",&T);
while(T--){
scanf("%d",&n);
ans = 0;
for(int i = 0; i < n; i++){
scanf("%d",&m);
sum = 0;
for(int j = 0; j < m; j++){
scanf("%d",&x);
sum +=(1<<(x-1));
}
ans ^= sg[sum];
}
if(ans)
printf("YES\n");
else{
printf("NO\n");
}
}
return 0;
}