zoukankan      html  css  js  c++  java
  • 【洛谷P2197】【模板】nim游戏【博弈论】

    题目大意:

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


    思路:

    NIMNIM博弈的模板。
    定理:NIMNIM博弈中先手必胜,当且仅当a1 xor a2 xor a3 xor...xor an>0a_1 xor a_2 xor a_3 xor...xor a_n>0

    N=a1 xor a2 xor a3 xor...xor anN=a_1 xor a_2 xor a_3 xor...xor a_n
    因为ax0a_xgeq0,所以显然N0Ngeq0
    首先,当所有石子全部被取完时,显然有N=0N=0。此时先手处于必败态
    如果N>0N>0,那么设NN二进制下从左往右数第一位为1的是第kk位,那么必然有奇数堆石子的第kk位为1,设第ii堆石子的第kk位为1,那么就从ii中取出若干石子,使得aia_i变为ai xor Na_i xor N(显然ai xor N<aia_i xor N<a_i)。由于数量为奇数,那么取完的必然是先手,此时有N=0N=0
    通过数学归纳法可得,N=0N=0时先手为必败态,N>0N>0时先手为必胜态。

    证明过程很粗略而不严谨,大概是这个意思好了:):)


    代码:

    #include <cstdio>
    using namespace std;
    
    int T,n,ans,x;
    
    int main()
    {
    	scanf("%d",&T);
    	while (T--)
    	{
    		scanf("%d",&n);
    		ans=0;
    		for (int i=1;i<=n;i++)
    		{
    			scanf("%d",&x);
    			ans^=x;
    		}
    		if (!ans) printf("No
    ");
    			else printf("Yes
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Vue vue-resource三种请求数据方式pet,post,jsonp
    Vue 各个阶段生命周期函数
    Vue v-if和v-show的使用.区别
    vue v-for循环中key属性的使用
    vue v-for循环使用
    Vue 设置style属性
    Vue 设置class样式
    Vue 双向数据绑定v-model
    Vue的事件修饰符
    关于“svn: Can't connect to host '*.*.*.*': 由于连接方在一段时间后没有正确答复或连接”的解决方法
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998097.html
Copyright © 2011-2022 走看看