洛谷 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;
}
posted @ 2021-06-13 21:46  尹昱钦  阅读(54)  评论(0编辑  收藏  举报