题解 UVA1566【John】

$\text{Link}$

题意

$\text{Anti Nim}$ 博弈。

有 $n$ 堆石子,第 $i$ 堆石子有 $a_i$ 颗,双人博弈,每次可以取走某堆石子的任意颗。取走最后一颗石子的人输,求先手是否有必胜策略。

思路

类似的,$\text{Anti Nim}$ 博弈的 $\text{SG}$ 函数与 $\text{Nim}$ 游戏一样,都是 $f(x)=\text{xor}_{i=1}^na_i$,当且仅当 $f(x)\ne0$ 时先手有必胜策略。

我们考虑胜利条件:

  1. $f(x)=0$ (即 $2|n$)且 $a_i$ 全都是 $1$;
  2. $f(x)\ne0$ 且 $a_i$ 不全都是 $1$。

则我们可以根据 $a_i$ 是否全是 $1$ 进行分类讨论。

首先考虑 $a_i$ 全都是 $1$ 的情况。十分显然,若 $2|n$,先手必胜,否则后手必胜。

然后是至少有 $1$ 个 $a_i$ 大于 $1$ 的情况。讨论此时 $\text{SG}$ 函数 $f(x)$ 的值。

    1. $f(x)=0$,即至少有两堆石子的颗数大于 $1$。那么操作后 $f(x)$ 定不为 $0$。则先手必败。
    1. $f(x)\ne0$,则需将 $f(x)$ 变为 $0$ 即可,那么先手必胜。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
namespace IO{//by cyffff

}
const int N=1e6+10,mod=998244353;
int n,fl;
int SG;
int main(){
    int T=read();
    while(T--){
        n=read(),fl=0,SG=0;
        for(int i=1;i<=n;i++){
            int x=read();
            SG^=x,fl|=x>1;
        }
        string a="John",b="Brother";
        puts((fl?(SG?a:b):(n&1?b:a)).c_str());
    } 
    flush();
}

再见 qwq~

双倍经验:$\text{Link}$

posted @ 2021-08-02 12:17  ffffyc  阅读(6)  评论(0)    收藏  举报  来源