题意:

给你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. Redis Cluster 集群节点信息 维护篇(二)

    集群信息文件: # cluster 集群内部信息对应文件,由集群自动维护. /data/soft/redis/6379data/nodes-6379.conf 集群信息查看: ./redis-trib ...

  2. 电子邮箱、邮件地址、网站地址正则表达式!几个有用的RE、regex、regexp!

    几个常用的正则表达式! r"\w[-\w\.]*@\w[-\w]*(\.\w[-\w]*)+" 这个是电子邮件地址的. r"<TAG\b[^>]*<(. ...

  3. luogu P4116 Qtree3

    题目描述 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑点,若无,输出 ...

  4. Gradle使用及配置

    构建工具:Gradle(6.8) 下载地址:https://gradle.org/releases/ 下载最新版的二进制文件即可,下载"gradle-6.8.1-bin.zip文件,下载后完 ...

  5. std::thread线程库详解(3)

    目录 目录 前言 lock_guard scoped_lock (C++17) unique_lock shared_lock 总结 ref 前言 前两篇的博文分别介绍了标准库里面的线程和锁,这一次的 ...

  6. Centos7 添加用户及设置权限

    一.添加用户 1.登录root 用户 [gau@localhost /]$ su Password: # 输入密码 [root@localhost /]# 2.添加用户 [root@localhost ...

  7. 忒修斯的Mac

    我有一台Mac笔记本,用了快6年了,当初买它的时候还借了几千块. 三年前,它的屏幕坏了,修理的方式就是直接换屏,而换屏其实就是上半部分连壳带屏幕整个换掉,简单的说:另一台电脑的上半身嫁接过来. 今年, ...

  8. Linux下双网卡双ip-双外网网关-电信联通双线主机设置

    1.实现:通过运营商提供的智能DNS,把电信用户访问时,数据进电信的网卡,出来时也从电信的网关出来,访问联通时,从联通网卡时,联通网卡出.这样速度就会快,实现双线主机的功能. 2.网卡信息:电信IP( ...

  9. E2.在shell中正确退出当前表达式

    E2.在shell中正确退出当前表达式 优雅退出当前表达式 在shell里面输出复杂的多行表达时,经常由于少输入一个引号,一直无法退出当前的表达式求值,也没有办法终止它,以前只能通过两次Ctrl+C结 ...

  10. has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

    前端显示: has been blocked by CORS policy: Response to preflight request doesn't pass access control che ...