题意:
有n堆石子,每次可以从一堆至少取一个,然后最后取完石子的获胜。
刚开始小A可以从某堆取k个,或者不取,然后再开始比赛。
思考:
刚开始我用了那种思想,就是一人取一次,每次只取一个,所以我就看看是不是奇数,如果是就赢了,当然中间还要判断某个数减去k之后是否能变成奇数。当然这只是一种思想,不能保证每次都是正确的。
这题正解是尼姆博弈,对于这种取石子,每次至少取一个。如果异或和不为0那么先手就赢了,否则先手输,所以就看看最终异或和为多少就行。
代码:
思想:
int T,n,m,k;
int va[N];
signed main()
{
IOS;
cin>>n>>m;
int ans = 0;
for(int i=1;i<=n;i++)
{
cin>>va[i];
ans += va[i];
}
int suc = 0;
if(ans&1) suc = 1;
for(int i=1;i<=n;i++)
{
if(va[i]>=m&&(ans-va[i])&1) suc = 1;
}
if(suc) cout<<"YES\n";
else cout<<"NO\n";
return 0;
}
尼姆博弈:
int T,n,m,k;
int va[N];
signed main()
{
IOS;
cin>>n>>m;
int ans = 0;
for(int i=1;i<=n;i++)
{
cin>>va[i];
ans ^= va[i];
}
int suc = 0;
if(ans) suc = 1;
for(int i=1;i<=n;i++)
{
if(va[i]>=k)
{
int sum = ans;
sum ^= va[i];
sum ^= (va[i]-k);
if(sum) suc = 1;
}
}
if(suc) cout<<"YES\n";
else cout<<"NO\n";
return 0;
}
总结:
多多积累经验。