hdu 3537(博弈,翻硬币)
题意:给定了每个正面朝上的硬币的位置,然后每次可以翻1,2,3枚硬币,并且最右边的硬币开始必须是正面朝上的。
分析:
约束条件6:每次可以翻动一个、二个或三个硬币。(Mock Turtles游戏)
初始编号从0开始。
当N==1时,硬币为:正,先手必胜,所以sg[0]=1.
当N==2时,硬币为:反正,先手必赢,先手操作后可能为:反反或正反,方案数为2,所以sg[1]=2。
当N==3时,硬币为:反反正,先手必赢,先手操作后可能为:反反反、反正反、正反正、正正反,方案数为4,所以sg[2]=4。
位置x:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14...
sg[x]: 1 2 4 7 8 11 13 14 16 19 21 22 25 26 28…
看上去sg值为2x或者2x+1。我们称一个非负整数为odious,当且仅当该数的二进制形式的1出现的次数是奇数,否则称作evil。所以1,2,4,7是odious因为它们的二进制形式是1,10,100,111.而0,3,5,6是evil,因为它们的二进制形式是0,11,101,110。而上面那个表中,貌似sg值都是odious数。所以当2x为odious时,sg值是2x,当2x是evil时,sg值是2x+1.
这样怎么证明呢?我们会发现发现,
evil^evil=odious^odious=evil
evil^odious=odious^evil=odious
假设刚才的假说是成立的,我们想证明下一个sg值为下一个odious数。注意到我们总能够在第x位置翻转硬币到达sg为0的情况;通过翻转第x位置的硬币和两个其它硬币,我们可以移动到所有较小的evil数,因为每个非零的evil数都可以由两个odious数异或得到;但是我们不能移动到下一个odious数,因为任何两个odious数的异或都是evil数。
假设在一个Mock Turtles游戏中的首正硬币位置x1,x2,…,xn是个P局面,即sg[x1]^…^sg[xn]=0.那么无可置疑的是n必定是偶数,因为奇数个odious数的异或是odious数,不可能等于0。而由上面可知sg[x]是2x或者2x+1,sg[x]又是偶数个,那么x1^x2^…^xn=0。相反,如果x1^x2^…^xn=0且n是偶数,那么sg[x1]^…^sg[xn]=0。这个如果不太理解的话,我们可以先这么看下。2x在二进制当中相当于把x全部左移一位,然后补零,比如说2的二进制是10,那么4的二进制就是100。而2x+1在二进制当中相当于把x全部左移一位,然后补1,比如说2的二进制是10,5的二进制是101。现在看下sg[x1]^…^sg[xn]=0,因为sg[x]是2x或者2x+1,所以式子中的2x+1必须是偶数个(因为2x的最后一位都是0,2x+1的最后一位都是1,要最后异或为0,2x+1必须出现偶数次)。实际上的情况可能是这样的:
MT游戏当中的P局面是拥有偶数堆石子的Nim游戏的P局面。
这是翻硬币游戏里面种的一种,有了上面的理论之后这道题也就容易了!不过这道题要注意的地方就是去除重复位置!!
代码实现:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n, a[]; int main()
{
int flag, i, len, num, x;
while(scanf("%d",&n)!=EOF)
{
flag=;
if(n==)
{
printf("Yes\n");
continue;
}
for(i=; i<n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
len=;
a[len++]=a[];
for(i=;i<n;i++)
if(a[i]!=a[len-])
a[len++]=a[i]; for(i=; i<len; i++)
{
num=;
x=a[i]*;
while(a[i])
{
if(a[i]&)
num++;
a[i]=a[i]>>;
}
if(num%==)
x++;
flag=flag^x;
} if(flag)
printf("No\n");
else
printf("Yes\n");
}
return ;
}
hdu 3537(博弈,翻硬币)的更多相关文章
- HDU 3537 (博弈 翻硬币) Daizhenyang's Coin
可以参考Thomas S. Ferguson的<Game Theory>,网上的博客大多也是根据这个翻译过来的,第五章讲了很多关于翻硬币的博弈. 这种博弈属于Mock Turtles,它的 ...
- HDU 3537 基础翻硬币模型 Mock Turtles 向NIM转化
翻硬币游戏,任意选3个,最右边的一个必须是正面.不能操作者败. 基本模型..不太可能自己推 还是老实记下来吧..对于单个硬币的SG值为2x或2x+1,当该硬币的位置x,其二进制1的个数为偶数时,sg= ...
- hdu 3537 Daizhenyang's Coin(博弈-翻硬币游戏)
题意:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初始编号从0开始. 当N==1时,硬币为:正,先手必胜,所以sg[0]=1. 当N==2时,硬币为:反正,先手必赢,先手操作后 ...
- HDU 3537 Daizhenyang's Coin 翻硬币博弈
题意: 给你n个硬币,你可以从中拿出来1.2.3个硬币,它们不一定要连续,你只需要保证拿出来的硬币中那个下标最大的硬币一定要是正面朝上,最后谁不能操作,谁就输了 题解: 翻硬币游戏 结论: 局面的SG ...
- hdu 3537 翻硬币 每次能翻1个 或2个 或3个
N 枚硬币排成一排,有的正面朝上,有的反面朝上.我们从左开始对硬币按1 到N 编号. 第一,游戏者根据某些约束翻硬币,但他所翻动的硬币中,最右边那个硬币的必须是从正面翻到反面. 第二,谁不能翻谁输. ...
- HDU 3537 Mock Turtles型翻硬币游戏
题目大意: 每次可以翻1个或者2个或者3个硬币,但要保证最右边的那个硬币是正面的,直到不能操作为输,这题目还有说因为主人公感情混乱可能描述不清会有重复的硬币说出,所以要去重 这是一个Mock Turt ...
- 【hdu 3537】Daizhenyang's Coin
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...
- bzoj 3517: 翻硬币
3517: 翻硬币 Time Limit: 1 Sec Memory Limit: 128 MB Description 有一个n行n列的棋盘,每个格子上都有一个硬币,且n为偶数.每个硬币要么是正面 ...
- 51nod 1613翻硬币
题目链接:51nod 1613 翻硬币 知乎上的理论解法http://www.zhihu.com/question/26570175/answer/33312310 本题精髓在于奇偶性讨论. 若 n ...
随机推荐
- C#程序大打开
打开一个已经存在的工程: 1.用vs打开(.sln)解决方案的文件.(若提示VS提示版本不一致,可用方法二) 2.删除(.sln)的文件.打开项目(.csproj) 文件或 (.vbproj) 文件, ...
- 解决IIS应用程序池DefaultAppPool关闭超时错误
错误系统日志: 为应用程序池“DefaultAppPool”提供服务的进程关闭时间超过了限制.进程 ID 是“3060”. 有关更多信息,请参阅在http://go.microsoft.com/fwl ...
- Swift 使用CollectionView 实现图片轮播封装就是这样简单
前言: 这篇你可以学会自定义视图,创建collectionView,协议的使用,定时器; 自制图片 先上Demo:Github上封装好的下载即用, 好用请Star Thanks首先新建一个继承于UIV ...
- ssh2框架搭建
原文:ssh2框架搭建 struts2+spring4.0+hibernate4.0 4.x版本与3.x版本有较大区别,要配置方法须要注意,用到的jar包如下 文件结构 src/application ...
- ORA-00911无效字符报错
今天在修改缺陷时遇到一个问题,更新数据库字段时一直报错:ORA-00911.sql脚本如下: '; '; '; 该脚本在数据库中可以执行,但是从程序中去访问数据库修改值时就会报错. 报错的原因在于,更 ...
- [置顶] 炎炎夏日,给你一次极爽的开发体验!——统一开发环境功能升级优化,正式上线V2.0!
作为中国移动应用运行托管平台(MM应用引擎)的开发部署工具,统一开发环境(UDE)在原HTML5跨平台开发功能基础上优化升级,新增跨平台编译(Android/iOS)和云端托管服务,正式上线2.0版本 ...
- Android开发实例详解之IMF(Android SDK Sample—SoftKeyboard)
本博前面的文章介绍了Android开发环境的搭建和模拟器的常用操作.本次,将以Android Sample中经典的SoftKeyboard项目为例,详细解析Android上一个小型项目的开发过程和注意 ...
- MyBatis的foreach语句详解 list array map
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合.foreach元素的属性主要有 item,index,collection,open,separator,close.it ...
- 深入理解Java内存模型(三)——顺序一致性
数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代码 ...
- 深入理解Java内存模型(五)——锁
锁的释放-获取建立的happens before 关系 锁是java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息. 下面是锁释放-获取的示例代 ...