P4279 [SHOI2008]小约翰的游戏(Anti_nim)
题面
题目描述
小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有 \(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态必胜
先手把S2态变成T2态
后手只能把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)的更多相关文章
- 洛谷 P4279 [SHOI2008]小约翰的游戏 解题报告
P4279 [SHOI2008]小约翰的游戏 题目描述 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有\(n\)堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子 ...
- BZOJ 1022 Luogu P4279 [SHOI2008]小约翰的游戏 (博弈论)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=1022 (luogu) https://www.luogu.org/pro ...
- P4279 [SHOI2008]小约翰的游戏
嘟嘟嘟 一道博弈论经典题,nim游戏. 只不过要考虑有奇数个石子为1的堆的时候,为Brother赢.剩下就是nim游戏了. 极简代码 #include<cstdio> using name ...
- bzoj 1022: [SHOI2008]小约翰的游戏John anti_nim游戏
1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1189 Solved: 734[Submit][ ...
- SHOI2008小约翰的游戏John
1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1139 Solved: 701[Submit][ ...
- BZOJ 1022 [SHOI2008]小约翰的游戏John
1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1635 Solved: 1036[Submit] ...
- 1022: [SHOI2008]小约翰的游戏John
1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1322 Solved: 829[Submit][ ...
- 1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】
1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2709 Solved: 1726[Submit] ...
- bzoj千题计划112:bzoj1022: [SHOI2008]小约翰的游戏John
http://www.lydsy.com/JudgeOnline/problem.php?id=1022 http://www.cnblogs.com/TheRoadToTheGold/p/67448 ...
随机推荐
- 使用OpenCV和Python构建自己的车辆检测模型
概述 你对智慧城市的想法感到兴奋吗?如果是的话,你会喜欢这个关于建立你自己的车辆检测系统的教程的 在深入实现部分之前,我们将首先了解如何检测视频中的移动目标 我们将使用OpenCV和Python构建自 ...
- 基于python tkinter的课堂点名小程序
import datetime import json import os import random import tkinter as tk import openpyxl # 花名册文件名很多人 ...
- 11_IO多路复用
1.IO概述 input 和 output: 是在内存中存在的数据交换操作 内存和磁盘交换: 文件读写, 打印 内存和网络交换: recv send recvfrom, sendto IO密集型程序: ...
- IFile、File与实体转换
/** * 根据物理实体文件在开发工程中创建实体文件 */ @Override public void getEntityFilesByErFile(IFile erfile, IFolder ent ...
- LongAccumulator类的BUG——reset方法并不能保证初始值正确赋值
LongAccumulator.reset方法并不能重置重置LongAccumulator的identity:初始值正确,使其恢复原来的初始值.当初始值为0是不会发生这个问题,而当我们设置初始值如1时 ...
- HTML5总结整理
(仅供大家学习分享交流) 一.简介 1.前端开发最核心技术 我们知道,用所谓的网页三剑客已经不能满足需求了,那前端开发究竟要学习什么技术呢?网页最 主要由3部分组成:结构.表现和行为.网页现在新的标准 ...
- Odoo10.0中的工作流
Odoo10.0中可以通过两种方式来实现工作流(workflow) 一种的官网API中给出的方式,链接:https://www.odoo.com/documentation/10.0/referenc ...
- 【吴恩达课程使用】anaconda (python 3.7) win10安装 tensorflow 1.8 cpu版
[吴恩达课程使用]anaconda (python 3.7) win10安装 tensorflow 1.8 目前tensorflow是只支持到python3.6的,anaconda最新版本已经到pyt ...
- Centos7,PHP7安装swoole
Swoole详细介绍及如何使用,这里暂时不做说明,可以参考一下文档:https://wiki.swoole.com/ 源码编译安装 下载地址如下: https://github.com/swoole/ ...
- Linux实战(11):配置PPPOE拨号
前言: 由于需要做网站数据的抓取,普通的固定代理会容易被封禁,所以我们就用PPPOE通过动态拨号换不同的IP地址来解决该问题,下面PPPOE设置的整个方法过程: 移除NetworkManager安装r ...