HDU-5963 朋友 思维
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5963
吐槽
这道题我第一眼看,嗯??博弈论?还是树上的?我好像不会啊。。。但是一想某人的话,感觉这个应该也不会太难,可能有规律
分析
于是我就从样例开始仔细思考找规律,第一个样例应该是看不出来啥,但第二个内容量就比较丰富了。但我模拟完样例二依旧没发现什么,难道这道题真要建个线段树什么的??接着我把关注点放到了输出上,输出只有两种,那是不是应该存在某种奇偶关系?还是要先考虑链的情况,因为从无根树上的一个点出发遍历就相当于走几条链(好像树的问题大部分都跟链有关)。下面模拟一下
首先要注意到题目中的暗示,每次都要找一个到父亲节点权值为1的点,这就说明了这个问题的限制,它总会结束。先不考虑修改,如果以1为根,不难看出女孩会赢,其中一种走法是
当然也有别的走法,但总会是女生赢。
如果以2为根呢?不难得出还是女孩赢,其中一种走法为
那么是不是图中边权为1的边数为偶数时,就是女生赢呢?仍旧以2为根,我们在4后边再跟一个节点。
会发现这样还是女生赢。
那在根节点2后边跟这个节点呢?
这时候再去模拟就会发现是男生赢了。所以我们猜测,让女生赢的并不是图中边权为1的边数,而是根节点周围边权为1的边数,根据这个大胆的猜测,我写出了下面的代码,好像还白写了一个加边函数。如果你去用样例测试,发现是对的,所以我兴奋的交了上去,WA
#include<cstdio>
#include<cstring>
using namespace std;
const int N=4e4+10;
struct Edge{
int to,nxt,val;
}e[N<<1];
int Head[N],len;
void Ins(int a,int b,int c){
e[++len].to=b;e[len].val=c;
e[len].nxt=Head[a];Head[a]=len;
}
int cnt[N];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
memset(cnt,0,sizeof(cnt));
for(int i=1;i<n;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
cnt[a]+=c;
cnt[b]+=c;
}
for(int i=1;i<=m;i++){
int op,x,y,z;
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&x,&y,&z);
if(z==1)cnt[x]++,cnt[y]++;
else cnt[x]--,cnt[y]--;
}
else {
scanf("%d",&x);
if(cnt&1)printf("Girls win!\n");
else printf("Boys win!\n");
}
}
}
}
二次分析
既然这个代码过了样例,就说明它应该不是偶然,所以应该是我少考虑了什么。再回去读了一边题,发现题中并没有说当\(op==1\)时,变换的权值与原来的权值相等,也就是说如果我每次都把1变为0,0变为1,那么我上边的代码是可以的,也就是样例情况,但问题就出在它可能是1变为1,0变为0,所以每次必须扫描一边根周围的边权之和,即下边的代码。
#include<cstdio>
#include<cstring>
using namespace std;
const int N=4e4+10;
struct Edge{
int to,nxt,val;
}e[N<<1];
int Head[N],len;
void Ins(int a,int b,int c){
e[++len].to=b;e[len].val=c;
e[len].nxt=Head[a];Head[a]=len;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
memset(Head,0,sizeof(Head));
len=0;
for(int i=1;i<n;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
Ins(a,b,c);Ins(b,a,c);
}
for(int i=1;i<=m;i++){
int op,x,y,z;
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&x,&y,&z);
for(int i=Head[x];i;i=e[i].nxt)
if(e[i].to==y)e[i].val=z;
for(int i=Head[y];i;i=e[i].nxt)
if(e[i].to==x)e[i].val=z;
}
else {
int cnt=0;
scanf("%d",&x);
for(int i=Head[x];i;i=e[i].nxt)cnt+=e[i].val;
if(cnt&1)printf("Girls win!\n");
else printf("Boys win!\n");
}
}
}
}
证明
写完之后感觉就这么过去的话不是很好,万一猜错了就很尴尬,所以想一下证明。
为了简化问题,我们只把链的情况证明了就好。如果连接根节点的边权值为1,其余边有两种情况,一是全为1的,二是含0的,分开讨论一下。
如果含有0,
因为是女生先任意选点,所以让女生选择最后一个点,这样连接根节点的那条边就会被置为0,而因为含有0,所以肯定还会剩下边权为1的,这时由于男生不得不去变换边,所以一定会去变换权值为1的,由于根节点在男生变换的时候为0,所以这样的话只有可能是女生让根节点变为0,也就是只有女生会赢。
如果不含0都是1呢?那女生就可以一次性让男生没的变换,仍然是女生赢。
当连接根节点的边权值为0时就会反过来,证毕。
HDU-5963 朋友 思维的更多相关文章
- HDU 5963 朋友 (找规律,思维)
HDU 5963 朋友 题目大意 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点 ...
- HDU - 5963 朋友(思维题)
题干 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始,双 ...
- HDU 5963 朋友 【博弈论】 (2016年中国大学生程序设计竞赛(合肥))
朋友 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Descr ...
- HDU 5963 朋友(找规律博弈)
http://acm.hdu.edu.cn/showproblem.php?pid=5963 题意: 思路: 我们可以先只考虑单链,自己试几种案例就可以发现规律,只有与根相连的边为1时,只需要奇数次操 ...
- hdu 5963:朋友
刚看到这题时感觉是树上博弈,然后我开始用一维的数据找规律.发现在一维的树上,如果把各边的值合在一起当成一个二进制数,那么,ans只与奇偶性有关,于是,我提出了一个比较大胆的假设:若连接在root上的所 ...
- hdu 5963 朋友(2016ccpc 合肥站 C题)
朋友 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submissi ...
- 【不知道怎么分类】HDU - 5963 朋友
题目内容 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始 ...
- HDU 5963 朋友(树+博弈)
#include<vector> #include<cstdio> #include<cstring> #include<algorithm> #def ...
- 【博弈】HDU - 5963 朋友
题目 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始,双 ...
- 最简单的博弈论——HDU - 5963 朋友 (博弈)
OK,好的先看一下题意: B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根. ...
随机推荐
- MyISAM 和 InnoDB
1.MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级 ...
- Jenkins构建项目帮助文档
Jenkins构建项目帮助文档 主要步骤 一.配置jdk 1.1. 下载jdk,安装到自己电脑磁盘的Java目录下(比如:D:\Java\jdk). 1.2. Jdk环境变量的配置: 1. 鼠 ...
- OpenCV3入门(十三)图像运动模糊
1.原理 运动模糊产生: 由于相机传感器或物体相对运动, 按快门瞬间造成图像产生运动模糊. 在用摄像机获取景物图像时,如果在相机曝光期间景物和摄像机之间存在相对运动,例如用照相机拍摄快速运动的物体,或 ...
- AspNetCore源码解析_1_CORS中间件
概述 什么是跨域 在前后端分离开发方式中,跨域是我们经常会遇到的问题.所谓的跨域,就是处于安全考虑,A域名向B域名发出Ajax请求,浏览器会拒绝,抛出类似下图的错误. JSONP JSONP不是标准跨 ...
- C语言程序设计(三) 简单的算术运算和表达式
第三章 简单的算术运算和表达式 算数运算符:一元.二元.三元(条件运算符) 1/2是整型除法,1.0/2是浮点数除法 求余运算(%)限定参与运算的两个操作数必须为整数,不能对两个实型数据进行求余运算 ...
- Java反射之成员方法的反射
上一篇介绍了Java反射之成员变量的反射,这次介绍成员方法的反射. [一]Method类 Method类中封装了所有java方法的属性,包括该方法是否私有,该方法的修饰符,返回值,参数,抛的错误等等. ...
- Linux查看目录树形结构
安装tree. yum -y install tree 查看是否安装成功 yum list installed tree 执行tree命令查看目录树形结构 tree
- Centos7安装Elasticsearch和Kibana
这里使用的6.6.0版本,ES需要JDK环境,对应1.8 Elasticsearch安装: 1.下载:https://elasticsearch.cn/download/ 2.解压: 3.修改配置:j ...
- linux入门系列18--Web服务之Apache服务1
前面系列文章讲解了Linux下通过文件传输.文件共享.邮件系统来分享和获取资源,本文讲解网络资源获取和共享的另外一种形式,通过Apache服务程序来提供Web服务. 本文先讲解目前主流的Web服务程序 ...
- 控制游戏/app使用期限/过期,证书有效期,弹出公告支持离线使用/后端控制,支持Swift、Objective-C集成非常简单,永久免费框架
CertCheck.framework (for iOS) 只能运行于真机上,切勿在模拟器上使用 这是一个控制游戏/app使用期限(到设定的时间无法打开app),或发布弹出公告永久免费的框架,可以全版 ...