zoukankan      html  css  js  c++  java
  • 【bzoj1022】小约翰的游戏John

    Portal -->bzoj1022

    Solution

    ​   这题其实是裸的反Nim,这里主要是为了写反Nim游戏的证明

    ​   首先给出反Nim(anti-nim)的定义和结论:

    【定义】桌子上有 N 堆石子,游戏者轮流取石子; 每次只能从一堆中取出任意数目的石子,但不能不取;取走最后一个石子者败

    【结论】先手必胜当且仅当满足下面两个条件中的一个

    ​   (1)所有堆的石子数都为(1)且游戏的(sg)值为(0)

    ​   (2)有些堆的石子数大于(1)且游戏的(sg)值不为(0)

    ​ ​  

    ​   然后我们来证明anti-nim游戏的结论,可以分成两种情况讨论(以下内容摘自论文):

    1、每堆只有(1)个石子:

    ​   那么显然先手必胜当且仅当石子堆数(n)为偶数

    2、其他情况:

    ​​   (1)当游戏的(sg)值不为(0)时:若还有至少两堆石子的数目大于$ 1$,则先手将 (sg)值变为 (0)即可;若只有一堆石子数大于(1),则先手总可以将状态变为有奇数个(1)(可以把大于(1)的那堆直接取完或者取剩(1)个),所以,当(sg)不为(0)时先手必胜

    ​​   (2)当游戏的(sg)值为(0)时:至少有两堆石子的数目大于 (1),则先手决策完之后,必定至少有一堆的石子数大于 (1),且(sg)值(当前游戏局面的)不为(0),由上段的论证我们可以发现,此时,无论先手如何决策,都只会将游戏带入先手必胜局,所以先手必败

    ​  

    ​   代码大概长这个样子

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,T,ans,cnt;
    
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    #endif
    	int x;
    	scanf("%d",&T);
    	for (int o=1;o<=T;++o){
    		ans=0; cnt=0;
    		scanf("%d",&n);
    		for (int i=1;i<=n;++i){
    			scanf("%d",&x),ans^=x;
    			if (x>1) ++cnt;
    		}
    		if (cnt==0) printf(n%2?"Brother
    ":"John
    ");
    		else printf(ans?"John
    ":"Brother
    ");
    	}
    }
    
  • 相关阅读:
    Android睡眠唤醒机制--Kernel态
    android-铃声的设置与播放
    Android RingtoneManager 铃声管理
    RingtoneManager-获得系统当前的铃声
    Android RingtoneManager铃声管理
    android中常见声音操作方式(Ringtone,SoundPool,MediaPlayer)小结
    android 闹钟提醒并且在锁屏下弹出Dialog对话框并播放铃声和震动
    CSS中常见的BUG调试
    row_number() OVER (PARTITION BY COL1 ORDER BY COL2)
    android平台中,EventBus研究学习
  • 原文地址:https://www.cnblogs.com/yoyoball/p/9425543.html
Copyright © 2011-2022 走看看