• [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;
    }
    
  • 相关阅读:
    RSA加密解密算法
    PHP Request请求封装
    Mysql常用命令大全 sql
    [mysql] 修复问题表Table '.xxxx' is marked as crashed and should be repaired
    Allowed memory size of 134217728 bytes exhausted
    PHP $_SERVER['HTTP_REFERER'] 获取前一页面的 URL 地址
    windows 2012 如何设置取消禁拼ping
    Access提示Insert Into 语法错误解决办法总结
    Linux常用命令大全
    [转]临时表空间学习
  • 原文地址:https://www.cnblogs.com/-Wind-/p/11830368.html
Copyright © 2020-2023  润新知