HDU1850 尼姆博弈求可行方案数目
尼姆博弈(Nimm's Game)
题型
尼姆博弈模型,大致上是这样的:
有3堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取1个,多者不限,最后取光者得胜。
分析
1、首先自己想一下,就会发现只要最后剩两堆物品一样多(不为零),第三堆为零,那面对这种局势的一方就必败
那我们用(a,b,c)表示某种局势,首先(0,0,0)显然是必败态,无论谁面对(0,0,0) ,都必然失败;第二种必败态是(0,n,n),自己在某一堆拿走k(k ≤ n)个物品,不论k为多少,对方只要在另一堆拿走k个物品,最后自己都将面临(0,0,0)的局势,必败。仔细分析一下,(1,2,3)也是必败态,无论自己如何拿,接下来对手都可以把局势变为(0,n,n)的情形
那这种奇异局势有什么特点呢?
也不知谁这么牛逼,竟然能把这种局势和二进制联系在一起
这里说一种运算符号,异或'^',a^b=a'b+ab'(a'为非a)
我们用符号XOR表示这种运算,这种运算和一般加法不同的一点是1 XOR 1 = 0。先看(1,2,3)的按位模2加的结果:
1 = 二进制01
2 = 二进制10
3 = 二进制11 XOR
———————
0 = 二进制00 (注意不进位)
对于奇异局势(0,n,n)也一样,结果也是0
任何奇异局势(a,b,c)都有a XOR b XOR c = 0
如果我们面对的是一个非必败态(a,b,c),要如何变为必败态呢?
假设 a < b < c,我们只要将 c 变为a XOR b,即可。因为有如下的运算结果:
a XOR b XOR (a XOR b)=(a XOR a) XOR (b XOR b) = 0 XOR 0 = 0
要将c 变为a XOR b,只要对 c进行 c-(a XOR b)这样的运算即可
Being a Good Boy in Spring Festival
Problem Description
一年在外 父母时刻牵挂
春节回家 你能做几天好孩子吗
寒假里尝试做做下面的事情吧
陪妈妈逛一次菜场
悄悄给爸爸买个小礼物
主动地 强烈地 要求洗一次碗
某一天早起 给爸妈用心地做回早餐
如果愿意 你还可以和爸妈说
咱们玩个小游戏吧 ACM课上学的呢~
下面是一个二人小游戏:桌子上有M堆扑克牌;每堆牌的数量分别为Ni(i=1…M);两人轮流进行;每走一步可以任意选择一堆并取走其中的任意张牌;桌子上的扑克全部取光,则游戏结束;最后一次取牌的人为胜者。
现在我们不想研究到底先手为胜还是为负,我只想问大家:
——“先手的人如果想赢,第一步有几种选择呢?”
Input
输入数据包含多个测试用例,每个测试用例占2行,首先一行包含一个整数M(1<M<=100),表示扑克牌的堆数,紧接着一行包含M个整数Ni(1<=Ni<=1000000,i=1…M),分别表示M堆扑克的数量。M为0则表示输入数据的结束。
Output
如果先手的人能赢,请输出他第一步可行的方案数,否则请输出0,每个实例的输出占一行。
Sample Input
3
5 7 9
0
Sample Output
1
分析:由上分析可知,只要能对 c进行取走(c-(a XOR b))这样的操作即为可行方案
代码如下:
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
int n,p[111];
while(~scanf("%d",&n)&&n)
{
int sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&p[i]);
sum^=p[i];
}
if(!sum)//奇异局势
{
printf("0\n");
continue;
}
else
{
int cnt=0;
for(int i=0;i<n;i++)
{
if((sum^p[i])<p[i])//此方案下取p[i]-sum^p[i]张形成奇异局势
cnt++;
}
printf("%d\n",cnt);
}
}
return 0;
}
部分转自:https://www.cnblogs.com/jiangjun/archive/2012/11/01/2749937.html
HDU1850 尼姆博弈求可行方案数目的更多相关文章
- Being a Good Boy in Spring Festival 尼姆博弈
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Descr ...
- Being a Good Boy in Spring Festival(尼姆博弈)
Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 ...
- Being a Good Boy in Spring Festival(杭电1850)(尼姆博弈)
Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32 ...
- 尼姆博弈(Nimm's Game)
题型: 有3堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取1个,多者不限,最后取光者得胜. 思路 首先自己想一下,就会发现只要最后剩两堆物品一样多(不为零),第三堆为零,那面对这种局 ...
- 简单易懂的博弈论讲解(巴什博弈、尼姆博弈、威佐夫博弈、斐波那契博弈、SG定理)
博弈论入门: 巴什博弈: 两个顶尖聪明的人在玩游戏,有一堆$n$个石子,每次每个人能取$[1,m]$个石子,不能拿的人输,请问先手与后手谁必败? 我们分类讨论一下这个问题: 当$n\le m$时,这时 ...
- 题解报告:hdu 1850 Being a Good Boy in Spring Festival(尼姆博弈)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1850 Problem Description 一年在外 父母时刻牵挂春节回家 你能做几天好孩子吗寒假里 ...
- hdu----(1849)Rabbit and Grass(简单的尼姆博弈)
Rabbit and Grass Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 1849(Rabbit and Grass) 尼姆博弈
Rabbit and Grass Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- Light OJ 1393 Crazy Calendar (尼姆博弈)
C - Crazy Calendar Time Limit:4000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Su ...
随机推荐
- Python基础【day02】:数据运算(二)
本节内容 数据运算 表达式while 循环 一.数据运算 算数运算: 比较运算: 赋值运算: 逻辑运算: 成员运算: 身份运算: 位运算: #!/usr/bin/python a = 60 # 60 ...
- ChunkDisappearImage-一个以矩形为单位的图片消失分解效果
效果 使用 1.将ChunkDisappearImage挂在一个空GameObject上. 2.将ChunkDisappearImage的Material设为ChunkDisappearImageMa ...
- js对当前时间的相关操作
链接:https://www.cnblogs.com/visi_zhangyang/p/3490122.html js中获得当前时间是年份和月份,形如:201208 //获取完整的日期 v ...
- setTimeout设置不起作用
setTimeout立刻调用了 a()方法而不是xx秒以后,是因为调用方法时候没有加双引号. 正确做法:setTimeout(" a() ",5000): 调用 a() 方法时候要 ...
- 关于JS事件冒泡与JS事件代理(事件委托)
连接:https://blog.csdn.net/supercoooooder/article/details/52190100 核心代码: <ul id="parentUl" ...
- Java SE之Java工作原理
在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后 ...
- zabbix 源码分析 another/first network error wait for 15s seconds 出现原因及调优建议
在监控设备的时候,在server端的日志中有时候会见到类似another network error, wait for 15s seconds的异常,今天我们看下这个问题的出现原因和解决方案: 问题 ...
- Linux新增用户过程详解
Linux系统中,当使用useradd添加用户时,会将系统的/etc/skel目录下的所有文件复制到新添加用户的家目录中.该目录下的所有文件都是隐藏文件(以.点开头的文件). 通过修改.添加.删除/e ...
- 【vim】删除标记内部的文字 di[标记]
当我开始使用 Vim 时,一件我总是想很方便做的事情是如何轻松的删除方括号或圆括号里的内容.转到开始的标记,然后使用下面的语法: di[标记] 比如,把光标放在开始的圆括号上,使用下面的命令来删除圆括 ...
- Linux 文件系统扩展属性【转】
转自:https://blog.csdn.net/ganggexiongqi/article/details/7661024 扩展属性(xattrs)提供了一个机制用来将<键/值>对永久地 ...