HDU 3537 Daizhenyang's Coin 翻硬币博弈
题意:
给你n个硬币,你可以从中拿出来1、2、3个硬币,它们不一定要连续,你只需要保证拿出来的硬币中那个下标最大的硬币一定要是正面朝上,最后谁不能操作,谁就输了
题解:
结论:
局面的SG 值为局面中每个正面朝上的棋子单一存在时的SG 值的异或和。即一个有k个硬币朝上,朝上硬币位置分布在的翻硬币游戏中,SG值是等于k
个独立的开始时只有一个硬币朝上的翻硬币游戏的SG值异或和。比如THHTTH这个游戏中,2号、3号、6号位是朝上的,
它等价于TH、TTH、TTTTTH三个游戏和,即sg[THHTTH]=sg[TH]^sg[TTH]^sg[TTTTTH].我们的重点就可以放在单个硬币朝上时的SG值的求法。
(本篇文章T代表反面朝上,H相反)
根据上面的结论我们可以对题目上输入的THTTHT(假设的一个),SG(THTTHT)=SG(TH)^SG(TTTTH),因此我们只需要求出来H、TH、TTH、TTTH......所有的SG值就可以解决这一道题
初始化SG(T)=0
SG(H),H可以一次操作变成T,所以SG(H)=mex{SG(T)}=mex{0}=1 //mex就是求最小的不在这里面的值,不是负值
SG(TH),可以一次操作变成TT,HT,所以SG(TH)=mex{SG(TT),SG(HT)}=mex{SG(T),SG(H)}=mex{0,1}=2 //根据题意取出来硬币下标最大的应该是H,所以靠右边的T都没用
SG(TTH),可以一次操作变成HHT,TTT,THT,HTT,SG(TTH)=mex{SG(HH),SG(T),SG(TH),SG(H)}=mex{SG(H)^SG(TH),SG(T),SG(TH),SG(H)}
mex{1^2,0,2,1}=mex{3,0,2,1}=4;
通过求sg发现规律
sg 1 2 4 7 8 11 13 14
x 0 1 2 3 4 5 6 7
找到规律,sg[x],如果x的二进制1的个数为奇数,sg[x]=2*x ,否则 sg[x]=2*x+1;
然后把各个Sg的值异或最终就是答案
找规律代码:
1 #include <bits/stdc++.h>
2
3
4
5 using namespace std;
6
7
8
9 const int MAXN = 10005;
10
11
12
13 int SG[MAXN];
14
15 bool SGhash[MAXN];
16
17
18
19 inline int getSG(int x){
20
21 memset(SGhash,false,sizeof SGhash);
22
23 SGhash[0] = true;//翻一个硬币
24
25 for(int i=0 ; i<x ; ++i)SGhash[SG[i]] = true;//翻两个硬币
26
27 for(int i=0 ; i<x ; ++i)
28
29 for(int j=0 ; j<i ; ++j)SGhash[SG[i]^SG[j]] = true;//翻三个硬币
30
31 for(int i=0 ; ; ++i)if(!SGhash[i])return i;
32
33 }
34
35
36
37 inline void BuildSG(int x){
38
39 memset(SG,0,sizeof SG);
40
41 SG[0] = 1;//当head-up硬币位置在0时先手必胜
42
43 for(int i=1 ; i<=x ; ++i){
44
45 SG[i] = getSG(i);
46
47 }
48
49 }
50
51
52
53 int main(){
54
55
56
57 BuildSG(100);
58
59 for(int i=0 ; i<11 ; ++i)printf("%d:%d ",i,SG[i]);
60
61 printf("\n");
62
63 for(int i=11 ; i<20 ; ++i)printf("%d:%d ",i,SG[i]);
64
65
66
67 return 0;
68
69 }
代码:
1 #include <iostream>
2 #include <cstdio>
3 #include <set>
4 using namespace std;
5
6 int sg(int x){
7 int ans=0,tmp=x;
8 while( x>0 ){
9 if( (x&1) ) ans++;
10 x/=2;
11 }
12 if( (ans&1) ) return 2*tmp;
13 else return 2*tmp+1;
14 }
15
16 int main(){
17 int n,x;
18 while(scanf("%d",&n)!=EOF){
19 int ans=0,x;
20 set <int> mys;
21 for(int i=0;i<n;i++){
22 scanf("%d",&x);
23 mys.insert(x);
24 }
25 for(set <int>::iterator it=mys.begin();it!=mys.end();it++){
26 ans^=sg(*it);
27 }
28 if(ans==0) printf("Yes\n");
29 else printf("No\n");
30 }
31 return 0;
32 }
HDU 3537 Daizhenyang's Coin 翻硬币博弈的更多相关文章
- HDU 3537 Daizhenyang's Coin(博弈,翻硬币)
Daizhenyang's Coin Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU 3537 Mock Turtles型翻硬币游戏
题目大意: 每次可以翻1个或者2个或者3个硬币,但要保证最右边的那个硬币是正面的,直到不能操作为输,这题目还有说因为主人公感情混乱可能描述不清会有重复的硬币说出,所以要去重 这是一个Mock Turt ...
- hdu 3537 Daizhenyang's Coin(博弈-翻硬币游戏)
题意:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初始编号从0开始. 当N==1时,硬币为:正,先手必胜,所以sg[0]=1. 当N==2时,硬币为:反正,先手必赢,先手操作后 ...
- hdu 3537 Daizhenyang's Coin (翻硬币游戏)
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; ]; i ...
- HDU 3537 Daizhenyang's Coin
链接 [http://acm.hdu.edu.cn/showproblem.php?pid=3537] 题意 题意:已知一排硬币中有n个硬币正面朝上,输入正面朝上的硬币的位置ai.两人轮流操作, 每次 ...
- hdu 3537 Daizhenyang's Coin 博弈论
详见:http://www.cnblogs.com/xin-hua/p/3255985.html 约束条件6 代码如下: #include<iostream> #include<st ...
- HDU 3537 (博弈 翻硬币) Daizhenyang's Coin
可以参考Thomas S. Ferguson的<Game Theory>,网上的博客大多也是根据这个翻译过来的,第五章讲了很多关于翻硬币的博弈. 这种博弈属于Mock Turtles,它的 ...
- hdu 3537(博弈,翻硬币)
题意:给定了每个正面朝上的硬币的位置,然后每次可以翻1,2,3枚硬币,并且最右边的硬币开始必须是正面朝上的. 分析: 约束条件6:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初 ...
- 【hdu 3537】Daizhenyang's Coin
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...
随机推荐
- linux下的文件类型
在Linux中一切设备皆文件,首先来看一下Linux下的文件都有哪些分类,也就是文件类型 文件类型:普通文件(包括shell脚本,文档,音频,视频).目录文件.设备文件(又细分为字符设备文件和块设备文 ...
- Kubernetes K8S之kube-prometheus概述与部署
Kubernetes K8S之kube-prometheus概述与部署 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7. ...
- 【Linux】postfix大坑笔记
由于需要,想弄一个自动发送邮件的mailx或者sendmail 但是执行 echo "test" | mail -s "Worning mail !" xxxx ...
- 【ORA】Specified value of MEMORY_TARGET is too small, needs to be at least 3072M解决办法
今天安装EM12C的时候遇到了一个报错: 修改好数据库中的参数大小后,重新启动报错 Specified value of MEMORY_TARGET is too small, needs to be ...
- Xctf攻防世界—crypto—Normal_RSA
下载压缩包后打开,看到两个文件flag.enc和pubkey.pem,根据文件名我们知道应该是密文及公钥 这里我们使用一款工具进行解密 工具链接:https://github.com/3summer/ ...
- 利用sql_tuning_Advisor调优sql
1.赋权给调优用户 grant ADVISOR to xxxxxx; 2.创建调优任务 使用sql_text创建 DECLARE my_task_name VARCHAR2 (30); my_sqlt ...
- SQLSERVER 修改数据实例的排序规则
SQL Server服务器修改排序规则的方法 操作及验证步骤: 1 登录数据库后,查看当前安装数据库默认排序规则的两种方式 方式一.使用SQL Server 2014 Management Studi ...
- ovsdb-client命令
ovsdb-server 的命令行接口. 查看有哪些数据库: ovsdb-client list-dbs [server] 查看数据库 schema: ovsdb-client get-schema ...
- 代码 or 指令,浅析ARM架构下的函数的调用过程
摘要:linux程序运行的状态以及如何推导调用栈. 1.背景知识 1.ARM64寄存器介绍: 2.STP指令详解(ARMV8手册): 我们先看一下指令格式(64bit),以及指令对于寄存机执行结果的影 ...
- (17)-Python3之--文件操作
1.文件的操作流程 第一,建立文件对象. 第二,调用文件方法进行操作. 第三,不要忘了关闭文件.(文件不关闭的情况下,内容会放在缓存,虽然Python会在最后自动把内容读到磁盘,但为了以防万一,要养成 ...