题解 P2575 【高手过招】
VinstaG173 · · 题解
一道优秀的阶梯Nim+SG定理。
首先,我们在整个序列前面加上一个空格(设此时空格个数为
以下用■表示棋子,□表示空格。则对于这个场景:
(□)□■□□□□□□□□□□□□□□□□■■(样例第一组数据)
有第
将一个棋子移至右边第一个空格时,相当于将其与其右边相邻的所有棋子移到下一级阶梯。如这样:
(□)□■□□□□□□□□□□□□□□□□■■变成
(□)□□■□□□□□□□□□□□□□□□■■时相当于
#include<cstdio>
#include<cstring>
int T,N,K,cnt,tot,x,ans1,ans2;
bool hv[23];//hv[i]==true表示i位置有石子
int main()
{
scanf(" %d",&T);
while(T--)
{
scanf(" %d",&N);ans2=0;//整个数据的SG值用ans2储存
while(N--)
{
scanf(" %d",&K);
memset(hv,false,sizeof(hv));cnt=20-K+1;tot=0;ans1=0;//cnt即C,tot储存当前阶梯棋子个数,ans1储存本行SG值
while(K--)
{
scanf(" %d",&x);
hv[x]=true;//标记有石子
}
for(int i=1;i<=20;++i)
{
if(!hv[i])
{
if((--cnt)&1)ans1^=tot;//奇数级阶梯,异或
tot=0;
}
else ++tot;//加棋子到阶梯上
}
ans2^=ans1;//SG定理应用
}
if(ans2)printf("YES\n");
else printf("NO\n");
}
return 0;
}