数学-博弈论. 台阶-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;
}


posted @ 2022-07-23 16:28  lucky_light  阅读(114)  评论(0编辑  收藏  举报