题意:

给你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 翻硬币博弈的更多相关文章

  1. HDU 3537 Daizhenyang's Coin(博弈,翻硬币)

    Daizhenyang's Coin Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  2. HDU 3537 Mock Turtles型翻硬币游戏

    题目大意: 每次可以翻1个或者2个或者3个硬币,但要保证最右边的那个硬币是正面的,直到不能操作为输,这题目还有说因为主人公感情混乱可能描述不清会有重复的硬币说出,所以要去重 这是一个Mock Turt ...

  3. hdu 3537 Daizhenyang's Coin(博弈-翻硬币游戏)

    题意:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初始编号从0开始. 当N==1时,硬币为:正,先手必胜,所以sg[0]=1. 当N==2时,硬币为:反正,先手必赢,先手操作后 ...

  4. hdu 3537 Daizhenyang's Coin (翻硬币游戏)

    #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; ]; i ...

  5. HDU 3537 Daizhenyang's Coin

    链接 [http://acm.hdu.edu.cn/showproblem.php?pid=3537] 题意 题意:已知一排硬币中有n个硬币正面朝上,输入正面朝上的硬币的位置ai.两人轮流操作, 每次 ...

  6. hdu 3537 Daizhenyang's Coin 博弈论

    详见:http://www.cnblogs.com/xin-hua/p/3255985.html 约束条件6 代码如下: #include<iostream> #include<st ...

  7. HDU 3537 (博弈 翻硬币) Daizhenyang's Coin

    可以参考Thomas S. Ferguson的<Game Theory>,网上的博客大多也是根据这个翻译过来的,第五章讲了很多关于翻硬币的博弈. 这种博弈属于Mock Turtles,它的 ...

  8. hdu 3537(博弈,翻硬币)

    题意:给定了每个正面朝上的硬币的位置,然后每次可以翻1,2,3枚硬币,并且最右边的硬币开始必须是正面朝上的. 分析: 约束条件6:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初 ...

  9. 【hdu 3537】Daizhenyang's Coin

    Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

随机推荐

  1. 【SpringBoot1.x】SpringBoot1.x 开发热部署和监控管理

    SpringBoot1.x 开发热部署和监控管理 热部署 在开发中我们修改一个 Java 文件后想看到效果不得不重启应用,这导致大量时间花费,我们希望不重启应用的情况下,程序可以自动部署(热部署). ...

  2. 【SpringBoot1.x】SpringBoot1.x 检索

    SpringBoot1.x 检索 文章源码 概念 Elasticsearch 是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本.数字.地理空间.结构化和非结构化数据.Elasticse ...

  3. 【JavaWeb】JSP 页面

    JSP 页面 简介 JSP(Java Server Pages),即 Java 的服务器页面.它的主要作用是代替 Servlet 程序回传 HTML 页面的数据,因为 Servlet 程序回传 HTM ...

  4. 剑指Offer-连续子数组中的最大和

    题目 输入一个整型数组,数组里有正数也有负数.数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值.要求时间复杂度为 O(n). 输入 [1,-2,3,10,-4,7,2,-5] 返回值 ...

  5. MySQL45讲:一条update语句是怎样执行的

    首先创建一张表: create table T(ID int primary key,c int); 如果要更新ID=2这行+1:应该这样写 update T set c=c+1 where ID=2 ...

  6. QA职责

  7. row和statement

    [root@ma bin]# /usr/local/mysql/bin/mysqlbinlog -vv /var/lib/bin/mysql-bin.000013 --base64-output=DE ...

  8. kubernets之pod简介

    一  k8s集群里面的最小单位是pod 1.1 一个较为简单的pod的配置文件 apiverson: api的版本号 kind: 资源的种类 metadata: pod的种类等相关信息 spec: p ...

  9. [WPF] 在单元测试中使用 Prism 的 EventAggregator,订阅到 ThreadOption.UIThread 会报错

    1. 问题 [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { ContainerLocator ...

  10. Spring Boot Scheduled定时任务特性

    SpringBoot中的Scheduled定时任务是Spring Boot中非常常用的特性,用来执行一些比如日切或者日终对账这种定时任务 下面说说使用时要注意的Scheduled的几个特性 Sched ...