数学-博弈论. 台阶-Nim游戏
c++
AcWing 892. 台阶-Nim游戏
/*
* 题目描述:
* Acwing 892. 台阶-Nim游戏:
* 现在,有一个 n 级台阶的楼梯,每级台阶上都有若干个石子,其中第 i 级台阶上有 ai 个石子(i≥1)。
* 两位玩家轮流操作,每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中(不能不拿)。
* 已经拿到地面上的石子不能再拿,最后无法进行操作的人视为失败。
* 问如果两人都采用最优策略,先手是否必胜。
*
* 输入格式:
* 第一行包含整数 n。
* 第二行包含 n 个整数,其中第 i 个整数表示第 i 级台阶上的石子数 ai。
*
* 输出格式:
* 如果先手方必胜,则输出 Yes。
* 否则,输出 No。
*
* 数据范围:
* 1 ≤ n ≤ 10^5,
* 1 ≤ ai ≤ 10^9
*
* 解题思路:
* 台阶-Nim游戏作为经典博弈论内容,他的解题思路相比普通 Nim 游戏,加入了 **镜像操作** 这一内容
* 首先,我们考虑第 偶数 级台阶的作用。
* 倘若对手当前状态(仅考虑奇数级台阶,不考虑偶数台阶的情况下)为必负态,那么对手肯定想通过移动偶数台阶找到可以赢的方法。
* 但是,一定他移动某个偶数台阶的石子,我们就将这个石子接着往下移动,由原本的 i级台阶 -> i - 2级台阶,
* 仍然奇数台阶状态不被改变,对手仍为必负态。而偶数台阶经过对称操作,对手肯定也是输。
* 倘若对手当前状态(仅考虑奇数级台阶,不考虑偶数台阶的情况下)为必胜态,给我们移动到必负态,根据上面推论,我们肯定也赢不了。
*
* 那么奇数级台阶在什么条件下为必胜态呢?
* a1 ^ a3 ^ ... ^ a(2n-1) = 0, 必负态
* a1 ^ a3 ^ ... ^ a(2n-1) = x > 0, 必胜态
*
* 证明同 Nim 游戏一样,这里略过,可以简单说一下
* 必负态下,奇数台阶为必负,因为即使挪到偶数台阶情况下,对方可以通过镜像操作,一直使得我们保持必负态,直到所有台阶均无石子。
* 必胜态下,可以将对手直接转移动必负中去,证明同 Nim 游戏。
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 100010;
int a[N], n;
bool solution() {
int res = 0;
for (int i = 1; i <= n; i += 2) {
res = (res ^ a[i]);
}
if (res == 0) {
return false;
} else {
return true;
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) {
scanf("%d", &a[i]);
}
if (solution()) {
puts("Yes");
} else {
puts("No");
}
return 0;
}