Nim博弈
题意:
N堆石子,每堆里有\(a_i\)个石子,两个人可以拿每堆中的任意一个,问先手是否必胜
思路:
Nim博弈结论,\(a_1\) ^ \(a_2\) ^ \(.......\) ^ \(a_n\)是否等于 0
- 等于零先手必败
- 不等于零先手必胜
分析:首先先看这种情况就是每一个都一样
2 3
先手只需要先那第二堆中1个使其变成2 2
之后后手,无论做什么先手都对另一堆做镜像操作即可.
我们再拓宽下0 0 0 0
先手是必败的,
然后我们能知道有两种状态:
- 异或不等零: 异或值为x那么x二进制最高为的1在第k位上,那么至少存在一堆石子\(a_i\)他的第k位,是1,显然,p=\(a_i\)^x,p小于\(a_i\).我们从\(a_i\)中拿出p个即可,
\(a_1\) ^ \(a_2\) ^ $... ^ \(a_i\) ^ ....$ ^ \(a_n\)=x
\(a_1\) ^ \(a_2\) ^ $...^ \((a_i-p)\) ....$ ^ \(a_n\)
=\(a_1\) ^ \(a_2\) ^ $...^ ( \(a_i\) ^ \(x\)) ....$ ^ \(a_n\)
=x^x=0 - 异或值为0,无论如何去石子.得到的局面各堆石子异或起来都不等于0,
void solve()
{
cin>>n;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
ll sum=a[1];
for(int i=2;i<=n;i++){
sum^=a[i];
}
if(sum) puts("Yes");
else puts("No");
}