HDU 1850 Being a Good Boy in Spring Festival(博弈·Nim游戏)
Being a Good Boy in Spring Festival
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7382 Accepted Submission(s): 4490
春节回家 你能做几天好孩子吗
寒假里尝试做做下面的事情吧
陪妈妈逛一次菜场
悄悄给爸爸买个小礼物
主动地 强烈地 要求洗一次碗
某一天早起 给爸妈用心地做回早餐
如果愿意 你还可以和爸妈说
咱们玩个小游戏吧 ACM课上学的呢~
下面是一个二人小游戏:桌子上有M堆扑克牌;每堆牌的数量分别为Ni(i=1…M);两人轮流进行;每走一步可以任意选择一堆并取走其中的任意张牌;桌子上的扑克全部取光,则游戏结束;最后一次取牌的人为胜者。
现在我们不想研究到底先手为胜还是为负,我只想问大家:
——“先手的人如果想赢,第一步有几种选择呢?”
5 7 9
0
题意: 二人小游戏:m堆扑克牌,每次可以取其中一堆中的任意张,最后没有牌取了则为败者(即最后一次取牌的人为胜者)。这道题不是简单的直接判断是否先手能够获胜,而是求如果先手能够获胜,那么第一步有多少种可行方案数。如果先手不能获胜,输出0。
思路:
1.先直接求出先手是否能够获胜,方法是
对于一个Nim游戏的状态(a1,a2,...,an),如果a1^a2^...^an=0 ,那么先手必败。(也就是说,a1^a2^...^an !=0,那么先生必胜)
2.看能否通过减少其中某一堆的数量,使其变成必败状态。
令当前状态为sum,
如果能够获胜,那么sum = a1^a2^...^an != 0;
现在从第1堆开始看,能否通过减少第1堆中牌的数量(因为只能取牌,所以是减少牌的数目),使状态变为必败状态,
如果想让下一个状态为必败状态,那么只要让 a1' =a2^a3^...^an 即可(此时 ,a1'^a2^...^an =(a2^a3^...^an)^(a2^a3^...^an)
= 0 ,状态变为必败状态)
那么问题来了,当前牌的数目能变成 a1' 吗?也就是说a1能变成
a1' 吗?
这里只需要判断 a1 大于
a1' 就可以了:
a1 大于
a1',可以减少第1堆牌的数目变成必败状态。否则,不能。
相应的,通过判断 ai 大于
ai' : ai大于ai',可以减少第i堆牌的数目变成必败状态。否则,不能。
hint:这里在求ai' 的时候不必每次都求 a1^a2^...^ai -1 ^ ai +1^...^an ,而是利用第1步求出来的
当前状态 sum = a1^a2^...^an ,两边异或a1,
a1^sum =
a1^ a1^a2^...^an =
a2^...^an = a1'
a1' =a1 ^ sum
相应的 sum = a1^a2^...^ ai^...^an ,两边异或 ai,
ai^sum = a1^a2^...^ai ^ai ^...^an = ai'
ai' = ai ^ sum
推出,如果 (ai^sum) < ai ,那么方案可行。
代码:
#include<iostream>
#include<cstdio>
using namespace std; int main(){
int ni[110];
int m;
int i;
int sum;//状态
int ans;//可行的方案数
while(scanf("%d",&m),m){
sum=0;//初始化为0
for(i=0;i<m;i++){
scanf("%d",&ni[i]);
sum=sum^ni[i];
}
if(sum){
ans=0;
for(i=0;i<m;i++){
if((sum^ni[i])<ni[i]){//第i堆的数目多,可以减少第i堆数目,变成必败状态
ans++;
}
}
printf("%d\n",ans);
}
else{
printf("%d\n",0);
}
}
return 0;
}
HDU 1850 Being a Good Boy in Spring Festival(博弈·Nim游戏)的更多相关文章
- HDU 1850 Being a Good Boy in Spring Festival (Nim博弈)
Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32 ...
- hdu 1850 Being a Good Boy in Spring Festival(Nimm Game)
题意:Nimm Game 思路:Nimm Game #include<iostream> #include<stdio.h> using namespace std; int ...
- HDU.1850 being a good boy in spring festival (博弈论 尼姆博弈)
HDU.1850 Being a Good Boy in Spring Festival (博弈论 尼姆博弈) 题意分析 简单的nim 博弈 博弈论快速入门 代码总览 #include <bit ...
- HDU 1850 Being a Good Boy in Spring Festival
此题先考虑第一种,5 7 9的情况,先手如果想赢,则必定要把异或值变为0,因为随便取,所以此处的异或指的是对堆中的石子数进行异或,而非异或其SG函数. 首先7^9=14,因为要异或为0,则5要变成14 ...
- hdu 1850 Being a Good Boy in Spring Festival 博弈论
求可行的方案数!! 代码如下: #include<stdio.h> ]; int main(){ int n,m; while(scanf("%d",&n)&a ...
- HDOJ HDU 1850 Being a Good Boy in Spring Festival
Description 一年在外 父母时刻牵挂 春节回家 你能做几天好孩子吗 寒假里尝试做做下面的事情吧 陪妈妈逛一次菜场 悄悄给爸爸买个小礼物 主动地 强烈地 要求洗一次碗 某一天早起 给爸妈用心地 ...
- HDU 1850 Being a Good Boy in Spring Festival 在春节做乖孩子(Nim博弈,微变形)
题意: 思路: 如果全部扑克牌数目异或的结果ans为0,则必输,输出0.否则,必须要给对方一个P状态,可以对所有扑克堆进行逐个排查,将ans^a[i]就可以得到除了a[i]之外其他扑克数的异或结果tm ...
- 题解报告:hdu 1850 Being a Good Boy in Spring Festival(尼姆博弈)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1850 Problem Description 一年在外 父母时刻牵挂春节回家 你能做几天好孩子吗寒假里 ...
- HDU1850 Being a Good Boy in Spring Festival(博弈)
Being a Good Boy in Spring Festival Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I ...
随机推荐
- Vue 引入ElementUI 2.0.11:依赖未发现的问题
转自:https://blog.csdn.net/cslucifer/article/details/79019649
- 进程间通信(IPC)介绍(转)
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息. IPC的方式通常有管道(包括无名管道和命名管道).消息队列.信号量.共享存储.Socket ...
- (转)Spring对注解(Annotation)处理源码分析1——扫描和读取Bean定义
1.从Spring2.0以后的版本中,Spring也引入了基于注解(Annotation)方式的配置,注解(Annotation)是JDK1.5中引入的一个新特性,用于简化Bean的配置,某些场合可以 ...
- 事件绑定,事件捕获,事件冒泡以及事件委托,兼容IE
● 事件分为三个阶段: 事件捕获 --> 事件目标 --> 事件冒泡 ● 事件捕获:事件发生时(onclick,onmouseover……)首先发生在document上,然后依次传 ...
- 使用robotframework常见的几个问题
问题1:用rf运行IEdriver的速度好慢,比如在输入框输入用户名,一秒输入一个字符.你们的是不是这样子的?.如果是chromedriver就很快 解决办法:把IEDriver从64位换成32位 , ...
- 转 FreeBSD 安装JDK
cd /usr/ports/java/openjdk6make install clean 默认什么都不用选,因为我们配置的是运行环境, 中间编译过程好久... 偷懒的干脆就直接安装/usr/port ...
- Lua学习一----------开发环境搭建
© 版权声明:本文为博主原创文章,转载请注明出处 1.LuaDist下载地址:http://luadist.org/ 2.LuaRocks下载地址:https://github.com/luarock ...
- SQL Server中排名函数row_number,rank,dense_rank,ntile详解
SQL Server中排名函数row_number,rank,dense_rank,ntile详解 从SQL SERVER2005开始,SQL SERVER新增了四个排名函数,分别如下:1.row_n ...
- Jenkins:使用Git Parameter插件实现tag或分支的选择性构建
Jenkins如何选择任意一个tag来构建代码 Jenkins如何选择任意一个branch(分支)来构建代码 苦恼了一段时间后,发现Git Parameter插件实现可以帮助我们来实现. 下面来介绍如 ...
- HTTP状态码介绍详细
HTTP协议中几个状态码的含义:1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明 100 (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分, ...