题意
给一个\(n \times 20\)的棋盘,上面有一些棋子;对于一个棋子,能将它向右移动一格,如果右边有棋子,则向右跳到第一个空格,如果右边没有空格,则不能移动这个棋子,如果所有棋子都不能移动,那么将输掉这场比赛
判断先手必胜或者必败
思路
观察白格子的个数,设一段棋子右边的白格子个数为其层数,将棋子右移->将一个白格子移动到左边->这段棋子层数-1
这是个阶梯NIM的模型,即只考虑奇数层下的普通NIM游戏
Code
#include<bits/stdc++.h> #define Min(x,y) ((x)<(y)?(x):(y)) #define Max(x,y) ((x)>(y)?(x):(y)) using namespace std; typedef long long ll; int T,n; bool vis[21]; template <class T> void read(T &x) { char c; int sign=1; while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48; while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign; } int main() { read(T); while(T--) { int ans=0; read(n); for(int i=1;i<=n;++i) { memset(vis,0,sizeof(vis)); int m; read(m); int tot=0,cnt=21-m; for(int j=1;j<=m;++j) { int x; read(x); vis[x]=1; } for(int j=1;j<=20;++j) { if(!vis[j]) { if((--cnt)&1) ans^=tot; tot=0; } else ++tot; } } if(ans) puts("YES"); else puts("NO"); } return 0; }