Link

题面

题目描述

小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有 \(n\) 堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,

在这堆石子中取走任意多的石子,但不能一粒石子也不取,我们规定取到最后一粒石子的人算输。小约翰相当固执,他坚持认为先取的人有很大

的优势,所以他总是先取石子,而他的哥哥就聪明多了,他从来没有在游戏中犯过错误。小约翰一怒之前请你来做他的参谋。

自然,你应该先写一个程序,预测一下谁将获得游戏的胜利。

输入格式

本题的输入由多组数据组成,第一行包括一个整数 \(T\)(1≤T≤500),表示输入总共有 \(T\) 组数据。

每组数据的第一行包括一个整数 \(N\)(1≤N≤50),表示共有 \(N\) 堆石子,接下来有 \(N\) 个不超过 5000 的整数,分别表示每堆石子的数目。

输出格式

对于每组数据,如果约翰能赢得比赛,则输出 John,否则输出 Brother,请注意单词的大小写。

输入输出样例

输入 #1

2

3

3 5 1

1

1

输出 #1

John

Brother

说明/提示

对于 40% 的数据,T≤250

对于 100% 的数据,T≤500

题解

裸的Anti_nim 板子题。

Anti_nim 和普通的 nim 游戏的区别是取走最后一个的人输。

我们定义一下几种状态

T 态 亦或和为0

S 态 亦或和不为0

孤单堆 一堆仅有一个火柴

充裕堆 一堆有大于等于一根的火柴

T0 态 T态中充裕堆为0的状态

T2 态 T态中充裕堆数大于等于二的状态

S0 态 S态中充裕堆数位0的状态

S1 态 S态中充裕堆数为一的状态

S2 态 S态中充裕堆数大于等于二的状态

注:没有T1态,因为因为只有一个充裕堆时 其最高位对应>1 不会被异或消掉,也就是充裕堆会影响高位

引理1:

S0态必败,T0态必胜

这个就和普通的 nim 游戏一样

引理2:

S1态必胜

1.孤单堆为奇数时,拿走充裕堆就变成了 S0态

2.孤单堆为偶数时,那就把充裕堆拿成孤单堆,在重复情况1

引理3:

S2态不可能转化为 T0态

因为S2态至少有两个充裕堆,取一次最多减少一个充裕堆,但T0态没有一个充裕堆,所以不符合题意。

引理4:

S2态只要方法正确,可以一次性变成T2态。

S2态不能变成T0 态,又没有 T1 态,

又根据 S态能转化为 T 态,所以 S2 态只能转化为 T2 态

引理5

T2态只能转化为 S1态和S2态

首先T2不能转化为 S0态,因为两个充裕堆你没法一起取走。

假设我们T2态有两个充裕堆,取走一个就变成了一个也就是S1态。

有大于二个充裕堆时,取走之后充裕堆数大于等于一也就是 S2态。

引理6

S2态必胜

  1. 先手把S2态变成T2态

  2. 后手只能把T2态变为S1或S2态,变为S1态后手必败,先手必胜。变为S2态,先手可以重复步骤一。

所以S2态必胜

引理7

T2态必败

T2态只能转化为 S1态和 S2态,但那两个都是必胜态,所以T2必败

必胜态 T0,S1,s2

必败态 S0,T2

观察规律发现

1.每一堆石子只有一个时 且异或和为0
2.存在至少一堆石子多于一个时 且异或和不为0

先手必胜

SJ定理

定义 Anti_nim

决策集合为空时 当前者胜,其余同SG游戏

先手胜利,当且仅当

1.游戏SG函数不为0且某个单一游戏SG值大于1

2.游戏SG函数为0且任意单一游戏SG值=1

然后,这道题就变成了模板题

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int T,n,ans,cnt1,cnt2,num[55];
inline int read()
{
int s = 0,w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
return s * w;
}
int main()
{
T = read();
while(T--)
{
n = read(); ans = 0; cnt1 = 0, cnt2 = 0;
for(int i = 1; i <= n; i++)
{
num[i] = read();
ans ^= num[i];
if(num[i] > 1) cnt1++;
}
// cout<<ans<<" "<<cnt1<<endl;
if(ans == 0 && cnt1 == 0) printf("John\n");
if(ans != 0 && (cnt1 == 1 || cnt1 >= 2)) printf("John\n");
if(ans != 0 && cnt1 == 0) printf("Brother\n");
if(ans == 0 && cnt1 >= 2) printf("Brother\n");
}
return 0;
}

P4279 [SHOI2008]小约翰的游戏(Anti_nim)的更多相关文章

  1. 洛谷 P4279 [SHOI2008]小约翰的游戏 解题报告

    P4279 [SHOI2008]小约翰的游戏 题目描述 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有\(n\)堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子 ...

  2. BZOJ 1022 Luogu P4279 [SHOI2008]小约翰的游戏 (博弈论)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=1022 (luogu) https://www.luogu.org/pro ...

  3. P4279 [SHOI2008]小约翰的游戏

    嘟嘟嘟 一道博弈论经典题,nim游戏. 只不过要考虑有奇数个石子为1的堆的时候,为Brother赢.剩下就是nim游戏了. 极简代码 #include<cstdio> using name ...

  4. bzoj 1022: [SHOI2008]小约翰的游戏John anti_nim游戏

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1189  Solved: 734[Submit][ ...

  5. SHOI2008小约翰的游戏John

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1139  Solved: 701[Submit][ ...

  6. BZOJ 1022 [SHOI2008]小约翰的游戏John

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1635  Solved: 1036[Submit] ...

  7. 1022: [SHOI2008]小约翰的游戏John

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1322  Solved: 829[Submit][ ...

  8. 1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2709  Solved: 1726[Submit] ...

  9. bzoj千题计划112:bzoj1022: [SHOI2008]小约翰的游戏John

    http://www.lydsy.com/JudgeOnline/problem.php?id=1022 http://www.cnblogs.com/TheRoadToTheGold/p/67448 ...

随机推荐

  1. android开发之java代码中如何获取到当前时间。详情代码带注释。

    /** *获取当前时间 * @return */ public String getTime(){ Date date= new Date();//创建一个时间对象,获取到当前的时间 SimpleDa ...

  2. .net 安装部署诀窍

    1.解决方案资源管理器中有多个类库项目和一个启动主项目时:各类库项目的生成路径设为bin\debug: 启动主项目的生成路径设成指定的主输出路径: 2.打包时在应用程序文件夹中添加主输出即可,主输出的 ...

  3. Transform与Vector3 的API

    Transform.InverseTransformDirection(Vector3 direction) Vector3.ProjectOnPlane(Vector3 vector, Vector ...

  4. Springboot-Mybatis-进阶

    目录 数据库关系 ResultMap association collection 动态sql if where set choose foreach 缓存 一级缓存 二级缓存 开启二级缓存 配置 异 ...

  5. jinja2快速实现自定义的robotframework的测试报告

    一.背景 RF的结果报告可以方便我们查看每一条用例集.用例的执行结果统计,但是有的项目涉及到一些数据的比对,希望能够直观到看到数据,原生的测试报告就无法满足这个需求了. 原生的报告 项目需求报告格式 ...

  6. 执行Python程序出现“SyntaxError: Non-UTF-8 code starting with '\xb6'...”错误怎么办?

    如果文件中有中文,直接执行python xx.py会出现以下错误: SyntaxError: Non-UTF- code starting with '\xb6' in file XX.py on l ...

  7. Oracle用户自定义异常

    注意:普通的查询语句不会出现异常,只有使用into对变量进行赋值的时候才会发生异常 --系统变量: notfound --> if sql%notfund then 如果这个表达式为真,则 (增 ...

  8. sql如何查询不包含中文

    SELECT * FROM dbo.表名 WHERE 字段名 NOT LIKE '%[吖-座]%'

  9. Java 的各种内部类、Lambda表达式

    内部类 内部类是指在一个外部类的内部再定义一个类.内部类的出现,再次打破了Java单继承的局限性. 内部类可以是静态 static 的,也可用 public,default,protected 和 p ...

  10. pytest(1):安装与使用

    pytest介绍 1.pytest是比较成熟的一款python测试框架 2.简单灵活,容易上手,对比unitest框架更丰富. 3.单元测试和复杂的功能测试,都支持. 4.同时支持selenium,a ...