若一个游戏满足:
- 由两名玩家交替行动
- 在游戏进行的任意时刻,可以执行的合法行动与轮到哪位玩家无关
- 不能行动的玩家判负
则称该游戏为一个公平组合游戏。
尼姆游戏(NIM)属于公平组合游戏,但常见的棋类游戏,比如围棋就不是公平组合游戏,因为围棋交战双方分别只能落黑子和白子,胜负判定也比较负责,不满足条件2和3。
题目描述
给定n堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。
问如果两人都采用最优策略,先手是否必胜。
例如:有两堆石子,第一堆有2个,第二堆有3个,先手必胜。
操作步骤:
1. 先手从第二堆拿走1个,此时第一堆和第二堆数目相同
2. 无论后手怎么拿,先手都在另外一堆石子中取走相同数量的石子即可。
必胜状态和必败状态
在解决这个问题之前,先来了解两个名词:
- 必胜状态,先手进行某一个操作,留给后手是一个必败状态时,对于先手来说是一个必胜状态。即先手可以走到某一个必败状态。
- 必败状态,先手无论如何操作,留给后手都是一个必胜状态时,对于先手来说是一个必败状态。即先手走不到任何一个必败状态。
结论
假设n堆石子,石子数目分别是a1,a2,…,an,如果a1⊕a2⊕…⊕an≠0,先手必胜;否则先手必败。
证明
- 操作到最后时,每堆石子数都是0,0⊕0⊕…0=0
- 在操作过程中,如果 a1⊕a2⊕…⊕an=x≠0。那么玩家必然可以通过拿走某一堆若干个石子将异或结果变为0。
证明:不妨设x的二进制表示中最高一位1在第k位,那么在a1,a2,…,an中,必然有一个数ai,它的第k为时1,且ai⊕x<ai,那么从第i堆石子中拿走(ai−ai⊕x)个石子,第i堆石子还剩ai−(ai−ai⊕x)=ai⊕x,此时a1⊕a2⊕…⊕ai⊕x⊕…⊕an=x⊕x=0。 - 在操作过程中,如果 a1⊕a2⊕…⊕an=0,那么无论玩家怎么拿,必然会导致最终异或结果不为0。
反证法:假设玩家从第i堆石子拿走若干个,结果仍是0。不妨设还剩下a′个,因为不能不拿,所以0≤a′<ai,且a1⊕a2⊕…⊕a′⊕…⊕an=0。那么(a1⊕a2⊕…⊕ai⊕…an)⊕(a1⊕a2⊕…⊕a′⊕…⊕an)=ai⊕a′=0,则 ai=a′,与假设0≤a′<ai矛盾。
基于上述三个证明:
1. 如果先手面对的局面是a1⊕a2⊕…⊕an≠0,那么先手总可以通过拿走某一堆若干个石子,将局面变成a1⊕a2⊕…⊕an=0。如此重复,最后一定是后手面临最终没有石子可拿的状态。先手必胜。
2. 如果先手面对的局面是a1⊕a2⊕…⊕an=0,那么无论先手怎么拿,都会将局面变成a1⊕a2⊕…⊕an≠0,那么后手总可以通过拿走某一堆若干个石子,将局面变成a1⊕a2⊕…⊕an=0。如此重复,最后一定是先手面临最终没有石子可拿的状态。先手必败。
c++代码
#include <iostream>
#include <cstdio>
using namespace std;
/*
先手必胜状态:先手操作完,可以走到某一个必败状态
先手必败状态:先手操作完,走不到任何一个必败状态
先手必败状态:a1 ^ a2 ^ a3 ^ ... ^an = 0
先手必胜状态:a1 ^ a2 ^ a3 ^ ... ^an ≠ 0
*/
int main(){
int n;
scanf("%d", &n);
int res = 0;
for(int i = 0; i < n; i++) {
int x;
scanf("%d", &x);
res ^= x;
}
if(res == 0) puts("No");
else puts("Yes");
}
必败状态,先手无论如何操作,留给后手都是一个必胜状态时,对于先手来说是一个必败状态。即先手走不到任何一个必败状态。这句话是不是写错了,是先手走不到任何一个必胜状态吧。
这个是作者写错了吗 ,还是我们只是在第一层,作者在大气层
作者没错吧,先手走不到任何一个必败状态意思是先手拿完后,留给对面的一定是一个必胜状态,所以先手必败。
按你的说法,先手走不到任何一个必胜状态意思是先手拿完后,留给对面的一定是一个必败状态,那先手必胜
应该是这样理解的吧
必胜状态,先手进行某一个操作,留给后手是一个必败状态时,对于先手来说是一个必胜状态。即先手可以走到
(后手的)
某一个必败状态。必败状态,先手无论如何操作,留给后手都是一个必胜状态时,对于先手来说是一个必败状态。即先手走不到
后手
任何一个必败状态。tql
为什么ans要初始化成0呢,不应该初始化成第一个堆石子的数量吗
## 异或运算三个性质:
### ①任何数和 0做异或运算,结果仍然是原来的数
### ②任何数和其自身做异或运算,结果是 0
### ③异或运算满足交换律和结合律
xor is associative, commutative and invertible. 3 reasons why xor is used in nim games
这里能够使得执先手的一定胜利的大前提是:执先手的人足够聪明,每一次都能准确地找到ai-ai异或x(选法不一定唯一)。 这样就总能保证 自己 的下一个状态总是 非0 ,或者说是 对方回合的每一个状态都是 0,从而保证最终对方能够得到 00…000 这个失败状态,自己胜利
回来复习博弈论了,不得不说写的真的是太好了!!!狂赞
👍
胜负判定也比较负责 复杂吧, 写错字啦
qp+三连
古德
tql
###### 赞
# 赞
赞
%%%
#赞#
灰常好
写的好好!可以转载吗?会标明出处的!
这个证明过程非常易懂,赞
跪谢!!!
太清晰了