• luoguP4279 [SHOI2008]小约翰的游戏 Anti-SG 博弈论



    这就是一个Anti SG问题

    当整个游戏的(sg = 0)时,如果不存在单一游戏局面(sg > 1),那么先手必胜

    当整个游戏的(sg eq 0)时,如果至少存在一个单一游戏局面(sg > 1),那么先手必胜

    简略的证一下QAQ

    首先证(N)至少有一个后继是(P)

    • 整个游戏的(sg = 0),不存在单一游戏局面(sg > 1)

    一定有偶数个(1),显然先手必胜

    • 整个游戏的(sg eq 0),至少存在一个单一游戏局面(sg > 1)

    类似(Nim)游戏,先手一定可以选出一堆石头使得(sg = 0)

    然后是(P)的后继全部都是(N)

    • 整个游戏的(sg eq 0),不存在单一游戏局面(sg > 1)

    一定有奇数个(1),显然先手必败

    • 整个游戏的(sg = 0),至少存在一个单一游戏局面(sg > 1)

    由于(sg = 0),因此一定存在两个以上的单一游戏局面(sg > 1)

    此时,不论先手怎么取,后继状态的(sg)不可能等于(0),并且至少存在一个单一游戏局面(sg > 1)


    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define ll long long
    #define ri register int
    #define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
    #define drep(io, ed, st) for(ri io = ed; io >= st; io --)
    
    #define gc getchar
    inline int read() {
    	int p = 0, w = 1; char c = gc();
    	while(c < '0' || c > '9') { if(c == '-') w = -1; c = gc(); }
    	while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
    	return p * w;
    }
    
    int a[50050];
    
    int main() {
    	int T = read();
    	while(T --) {
    		int n = read();
    		rep(i, 1, n) a[i] = read();
    		int flag = 0, sg = 0, win;
    		rep(i, 1, n) flag += (a[i] > 1), sg ^= a[i];
    		if(!flag && sg == 0) win = 1;
    		else if(flag && sg != 0) win = 1;
    		else win = 0;
    		if(win == 1) printf("John
    ");
    		else printf("Brother
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    11 2
    10 29
    10 22
    dp的本质
    笛卡尔树小结
    Gitlab 备份迁移恢复报错gtar: .: Cannot mkdir: No such file or directory
    升级Jenkins版本
    当linux中的所有指令突然不能使用的时候
    合并范围
    每股收益列报计算
  • 原文地址:https://www.cnblogs.com/reverymoon/p/10151778.html
Copyright © 2020-2023  润新知