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;
    }
    
  • 相关阅读:
    人生转折点:弃文从理
    人生第一站:大三暑假实习僧
    监听器启动顺序和java常见注解
    java常识和好玩的注释
    182. Duplicate Emails (Easy)
    181. Employees Earning More Than Their Managers (Easy)
    180. Consecutive Numbers (Medium)
    178. Rank Scores (Medium)
    177. Nth Highest Salary (Medium)
    176. Second Highest Salary(Easy)
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998097.html
Copyright © 2011-2022 走看看