题目链接:https://ac.nowcoder.com/acm/problem/213157

到牛客看:https://blog.csdn.net/weixin_43346722/article/details/109343523

题目

Alice 和 Bob 从小就一起玩石子。
有一天,他们又想愉快的玩一个石子游戏。
一共有 堆石子,第 堆石子有 个,两人轮流操作。
Alice 走先手,每个人每个回合只能对一堆石子进行操作,Alice 每次操作只能拿偶数个石子,Bob 每次操作只能拿奇数个石子, 每次操作至少拿走一个石子,直到一方无法进行任何操作,无法操作的人失败。
假设Alice与Bob都是绝顶聪明的,如果 Alice 可以获胜,那么输出 YES,否则输出 NO。

输入

多组数据。对于每组数据,第一行输入一个正整数 ,第二行输入 个正整数,第 个数表示

输出

对于每组数据,每行输出一个字符串 YES 或 NO。

样例输入1

2
2 1

样例输出1

NO

样例输入2

1
6

样例输出2

YES

数据范围

对于 的数据,数据组数为
对于另外 的数据,
对于另外 的数据,石子数都为
对于 的数据 的和小于 ,石子数小于

思路

这道题是一道结论题。

先说说结论:Alice 能赢,当且仅当只有一堆数,而且数字是偶数。
(其实就是能一次性取完所有的东西,让 Bob 没有东西可以取)

那为什么一让 Bob 能取东西 Alice 就输了呢?
我们分开来看 Bob 要取东西的时候的情况:

  1. 场上还有数字是偶数的堆,那 Bob 就可以吧一个偶数堆取剩一个,这样 Alice 就取不了这一堆,而且 Bob 还可以再取一次。这样一直下去,显而易见,Bob 会有很多一个 可以用,就到了接下来的第二种情况。
  2. 场上没有数字是偶数的堆,那 Bob 就取走一整个堆。接着再分开来看:如果没有堆了,那接下来是 Alice 行动,那 Alice 没得取,就输了。如果还有奇数堆,那 Alice 只能把其中一个取到 ,然后让 Bob 把这个 取完,那一个堆消失之后还是要从 Alice 开始。那无论如何,Alice 都会输。

那我们可以发现要让 Alice 赢,就一定要让 Bob 没有拿东西的机会,那就只有当只有一堆数,而且数字是偶数的情况了。

(当然,也有通过看他们两个取奇数堆偶数堆对奇偶数堆数量的改变从而得出结论的方法,但是我比赛用的就是上面的方法)

这里再讲一讲看他们两个取奇数堆偶数堆对奇偶数堆数量的改变从而得出结论的方法吧。
可以发现,我们假设当前奇数堆有 个,偶数堆有 个。
那 Alice 取奇数堆,就变成了 (因为无论怎么取,还是会剩下奇数个)
那 Alice 取偶数堆,就变成了 (直接取完,不给机会)
那 Bob 取奇数堆,就变成了 (直接取完,不给机会)
那 Bob 取偶数堆,就变成了 (偶数 奇数 奇数,众所周知

可以发现,Alice 只能改变 ,而 里面的数取到 就不能取了,那 Bob 两个都可以减少。而且,就算 Alice 能每次把奇数堆 ,那 Bob 见状也一定会反手把你弄成 ,让你不能再取。
所以也可以得出上面的结论。

比赛时

看了挺久的,一开始还以为是 dp 之类的玩意儿。

后来看出来了,就码出来了。

图片说明

代码

#include<cstdio>

using namespace std;

int n, x, re;
char c;

int read() {
    re = 0;
    c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') {
        re = re * 10 + c - '0'; 
        c = getchar();
    }
    return re;
}

int main() {
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; i++) x = read();
        if (n == 1 && x % 2 == 0) printf("YES\n");
            else printf("NO\n");
    }

    return 0;
}