zoukankan      html  css  js  c++  java
  • [Nim游戏]

    [模板]Nim游戏

    题目描述

    甲,乙两个人玩Nim取石子游戏。
    nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取完,不能不取。每次只能从一堆里取。最后没石子可取的人就输了。假如甲是先手,且告诉你这n堆石子的数量,他想知道是否存在先手必胜的策略。

    结论:所有石子异或和为0则先手必败

    证明:

    (1):输的状态最后肯定是每堆都没有石子,此时所有石子异或和为(0^0^0^0......^0 = 0)

    (2):我们设所有石子的异或和为(k)(k)的最高位为第(i)位,则其中必定有一堆石子的第(i)位为(i)(异或的性质),我们设这堆石子为(H),其余所有石子异或和为(x),那么(H)$x$$=$$k$,那么有$H$(k)(=)(x),所以((H)$k$)(x)(=)(0)

    (3):所以我们得出:如果先手异或和不为(0),可以一步让后手的情况为异或和为(0);如果先手异或和为(0),那么后手异或和就不为(0)

    (4):现在假设开始时所有石子的异或和不为(0),则先手可以一直让后手的异或和为(0)(也就是(2)中的操作),最终后手会走向所有石子都是(0)的情况,则后手败,反之开始时所有石子的异或和为(0),那么后手也可以使得先手的异或和一直为(0),那么先手最终会走向所有石子都是(0)的情况,则先手败。

    所以结论得以证明。

    #include <cstdio>
    #include <iostream>
    using namespace std;
    int T,n,ans;
    int main()
    {
    	scanf("%d",&T);
    	while(T --)
    	{
    		scanf("%d",&n);
    		ans = 0;
    		for(int i=1;i<=n;i++)
    		{
    			int x;
    			scanf("%d",&x);
            	ans ^= x;
    		}
    		if(ans)
    			printf("Yes
    ");
        	else printf("No
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    通过通过url routing解决UIViewController跳转依赖
    vs2010下配置CUDA出现kernel launch failed问题,内核无效
    ganglia监控自己定义metric实践
    faq
    Android进阶图片处理之三级缓存方案
    操作系统 内存管理(一)
    rocketmq消费队列代码
    网页固定側栏的做法
    web爬虫之登录google paly 商店
    C之内存地址
  • 原文地址:https://www.cnblogs.com/-Wind-/p/11830368.html
Copyright © 2011-2022 走看看