每一行都是一个子游戏,很容易想到SG,对每一个子游戏而言最终状态为1全部都在最后,这和标准的阶梯游戏将所有的石子(随便一个代号)全部放到地上一样,不过这里的地面是指最后连续为1的部分,那阶梯的段数是怎样的呢?当该位置为0,则该“阶梯”上的石子数为1,是新的一段,所以段数为上一个阶梯+1,当该位置为1时,它和它左边连续的1构成一个“阶梯”,它上面的石子数为连续的1的个数,同样段数为上一阶梯+1,这样就成功的把这题的情形转化为阶梯模型,则该行的SG值为所有奇数阶梯的异或和
ACCode
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const ll inf =1e18;
const int N = 1e3+100;
int sg[N];
int vis[25];
vector<int> vec;
int main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
memset(sg, 0, sizeof(sg));
int n,ret=0; cin >> n;
for (int k = 1; k <= n; k++) {
int cnt,num=0; cin >> cnt;
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= cnt; i++) {
int temp; cin >> temp;
vis[temp] = 1;
}
bool sign = true;
int right = 20;
while (vis[right])--right;
right = min(right, 19);
int t_ret = 0;
for (right; right >= 1; right--) {
if (vis[right]) num++;
else {
if (sign) t_ret ^= num;
num = 0;
sign = !sign;
}
}
if (sign) t_ret ^= num;//注意可能最左端都为1,上面判断不到,我少了这卡了一下午233
ret ^= t_ret;
}
if (ret == 0) {
cout << "NO" << endl;
}
else {
cout << "YES" << endl;
}
}
}