Nim博弈

链接

题意:

N堆石子,每堆里有\(a_i\)个石子,两个人可以拿每堆中的任意一个,问先手是否必胜

思路:

Nim博弈结论,\(a_1\) ^ \(a_2\) ^ \(.......\) ^ \(a_n\)是否等于 0

  • 等于零先手必败
  • 不等于零先手必胜

分析:首先先看这种情况就是每一个都一样
2 3
先手只需要先那第二堆中1个使其变成2 2
之后后手,无论做什么先手都对另一堆做镜像操作即可.

我们再拓宽下0 0 0 0 先手是必败的,

然后我们能知道有两种状态:

  1. 异或不等零: 异或值为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
  2. 异或值为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");
}
posted @ 2021-07-23 09:48  `KingZhang`  阅读(36)  评论(0编辑  收藏  举报