BZOJ 1022: [SHOI2008]小约翰的游戏John【Anti-SG游戏与SJ定理】

博客主要对Anti - SG游戏(决策集合为空者胜)进行分析。探讨了游戏的三种情况,包括每堆只有一个石子、只有一堆石子数>1、存在至少两堆石子>1时的胜负判断。还根据nim游戏原理分析了不同状态的胜负关系,最后拓展介绍了SJ定理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目分析:

Anti-SG游戏(决策集合为空者胜)
针对这道题口胡一通。
游戏分三种情况:(下面的异或和指的是所有堆的SG值的异或和)

  • 每堆只有一个石子,此时
    • 若异或和为0(偶数堆),则先手必胜 (A)
    • 若异或和为1(奇数堆),则先手必败 (B)
  • 只有一堆石子数>1,(C)
    • 若有奇数堆石子数为1的,那么先手把当前堆取完即可,先手必胜
    • 若有偶数堆石子数为1的,那么先手把当前堆取成只剩一个石子,仍然是先手必胜
    • 注意,这时所有堆的SG值异或和一定不为0
  • 存在至少两堆石子>1
    • 异或和为0 (D)
    • 异或和不为0 (E)

根据nim游戏的原理,我们分析一下D、E状态的胜负:
首先,C状态是必胜状态,D、E状态最终都会归结到C状态。
E状态一定可以转移到D状态(因为只有一堆>1时异或和一定不为0,所以转移后仍然有至少两堆>1);
而D状态要么转移到E状态,要么转移到C状态。
所以E是必胜状态,D是必败状态。

应该解释明白了吧。。

拓展一下,就是SJ定理:

对于任意一个Anti-SG游戏,如果我们规定当局面中所有的单一游戏的SG值为0时,游戏结束,则先手必胜当且仅当:

  • 游戏中没有单一游戏的SG函数大于1 且 游戏的SG函数为0。
  • 游戏中存在某个单一游戏的SG函数大于1 且 游戏的SG函数不为0。

这道题的Code:

#include<cstdio>
#include<cctype>
#include<cstring>
#define maxn 5
inline void read(int &a){
    char c;while(!isdigit(c=getchar()));
    for(a=c-'0';isdigit(c=getchar());a=a*10+c-'0');
}
int n,x,T;
int main()
{
    read(T);
    while(T--){
        read(n);int ans=0,y=0;
        while(n--) read(x),ans^=x,y|=(x>1);
        puts((!y&&!ans)||(y&&ans)?"John":"Brother");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值