洛谷 P2197 【模板】nim 游戏(博弈论)
传送门
nim博弈
很典型的一种博弈。
我们考虑每堆石子的异或和。
若异或和为0,则必败,若非零,则必胜。
因为我们每一步都可以从一个异或和非零的状态转移到异或和为0的状态。
而最终每堆都是零时,异或和恰好为0(必败)。
如何证明?
考虑异或的性质,把数量最多的那一堆石子 \(k\) 单独拿出来看,要让异或和为0,只需要满足在原来异或和为1的位上是k变成相反的数。
举个例子
假设原来异或和为 \(11010110\)
而 \(k=10001010\) (显然,k的最高位一定是1)
我们只需要保证最终 \(k=01011100\),新的异或和一定为0。
所以总结一下就是看一开始的异或和是否为0,若等于0先手必败,否则先手必胜。
AC代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
using namespace std;
int t,n,ans;
int main(){
cin>>t;
while(t--){
ans=0;
cin>>n;
while(n--){
int a;
cin>>a;
ans^=a;
}
if(ans) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}