题解 UVA1566【John】
题意
$\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$ 时先手有必胜策略。
我们考虑胜利条件:
- $f(x)=0$ (即 $2|n$)且 $a_i$ 全都是 $1$;
- $f(x)\ne0$ 且 $a_i$ 不全都是 $1$。
则我们可以根据 $a_i$ 是否全是 $1$ 进行分类讨论。
首先考虑 $a_i$ 全都是 $1$ 的情况。十分显然,若 $2|n$,先手必胜,否则后手必胜。
然后是至少有 $1$ 个 $a_i$ 大于 $1$ 的情况。讨论此时 $\text{SG}$ 函数 $f(x)$ 的值。
-
- $f(x)=0$,即至少有两堆石子的颗数大于 $1$。那么操作后 $f(x)$ 定不为 $0$。则先手必败。
-
- $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}$

浙公网安备 33010602011771号