zoukankan      html  css  js  c++  java
  • 51Nod 1069:Nim游戏(尼姆博弈)

    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
     收藏
     关注
    有N堆石子。A B两个人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N及每堆石子的数量,问最后谁能赢得比赛。
    例如:3堆石子,每堆1颗。A拿1颗,B拿1颗,此时还剩1堆,所以A可以拿到最后1颗石子。
    Input
    第1行:一个数N,表示有N堆石子。(1 <= N <= 1000)
    第2 - N + 1行:N堆石子的数量。(1 <= A[i] <= 10^9)
    Output
    如果A获胜输出A,如果B获胜输出B。
    Input示例
    3
    1
    1
    1
    Output示例
    A

    这种情况与二进制有密切关系,我们用(a,b,c)表示某种局势,首先(0,0,0)显然是奇异局势,无论谁面对奇异局势,都必然失败。第二种奇异局势是(0,n,n),只要与对手拿走一样多的物品,最后都将导致(0,0,0)。仔细分析一下,(1,2,3)也是奇异局势,无论对手如何拿,接下来都可以变为(0,n,n)的情形。
    计算机算法里面有一种叫做按位模2加,也叫做异或的运算,我们用符号(+)表示这种运算。这种运算和一般加法不同的一点是1+1=0。先看(1,2,3)的按位模2加的结果:
    1 =二进制01
    2 =二进制10
    3 =二进制11 (+)
    ———————
    0 =二进制00 (注意不进位)

    对于奇异局势(0,n,n)也一样,结果也是0。
    任何奇异局势(a,b,c)都有a(+)b(+)c =0。

    如果我们面对的是一个非奇异局势(a,b,c),要如何变为奇异局势呢?假设 a < b< c,我们只要将 c 变为 a(+)b,即可,因为有如下的运算结果: a(+)b(+)(a(+)b)=(a(+)a)(+)(b(+)b)=0(+)0=0。要将c 变为a(+)b,只要从 c中减去 c-(a(+)b)即可。

                                                                                                                                                                                     

    简单的说就是数组中的所有元素,a1^a2^a3^......^an=k,如果k=0,则先拿的人输,否则后拿的人输

    #include <bits/stdc++.h>
    const int maxn=1e6+10;
    int a[maxn];
    int main()
    {
    	int n;
    	int sum=0;
    	scanf("%d",&n);
    	for(int i=0;i<n;i++) 
    	{
    		scanf("%d",&a[i]);
    		sum=sum^a[i];
    	}
    	if(sum==0) printf("B
    ");
    	else printf("A
    ");
    	return 0;
    }

    关于这道题的拓展可以看牛客的小白月赛2的E题:传送门

  • 相关阅读:
    接口测试-postman
    select
    SQLserver的七种约束。
    数据库的创建、表的创建。
    vim编辑器删除键失效
    客户端通过 HTTP 请求的 Header 信息总结
    清理/boot目录内容
    CentOS 7 配置samba 和 autofs
    CentOS 7 配置 nfs 和 autofs
    tftp简单文件传输协议基本配置
  • 原文地址:https://www.cnblogs.com/Friends-A/p/9309006.html
Copyright © 2011-2022 走看看