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
    ");
    	}
    }
    
  • 相关阅读:
    在Visual Studio中启用对jquery等javascript框架的智能感知
    网页的复制和防复制
    发现数据库对象的依赖关系
    这个世界并不缺少创意,而是缺少发现
    如何在ASP.NET程序中使用报表查看器控件并传递用户凭据
    Jquery调用webService的四种方法 【转载】
    浏览器的多线程技术
    .NET Framework 2.0的客户端是否可以调用WCF?
    在页面中实现内容的展开和收缩
    面向接口的编程(WCF)
  • 原文地址:https://www.cnblogs.com/yoyoball/p/9425543.html
Copyright © 2011-2022 走看看