Gym 101128 B Black Vienna
题意
有A-Z 26张牌,现在从中抽出3张牌,并把剩下的23张牌分给选手1和2,现在有n次询问,每次询问一个选手是否有某两张牌,和选手的回答。回答说自己有这两张牌中的几张,问拿出的三张牌有多少种方案能够满足这n个条件?n<=50
分析
个人感觉这个题是个很不错的题呢。
并查集的应用,有点像那道“关押罪犯”的升级版?www.cnblogs.com/LQLlulu/p/8819599.html
数据很小,只有26张牌和50个询问。那么三重循环枚举抽哪三张牌。对于每次抽出的三张牌,判断一下能否满足这n个询问,如果满足的话ans++。
但是怎么判断?
因为只有两个玩家,那么对于每张牌,如果这张牌没有被抽走,那么要么属于玩家1,要么属于玩家2。对于大多数情况我们都可以通过记录每张牌的归属判断是否冲突。
但是有一种特殊情况:
此时两张牌都未被抽走,而且回答是1。也就是说,这两张牌里有一张是属于这个人,另一张属于另一个玩家。那么我们此时没法直接记录。因为我们并不能知道哪张牌属于谁,只能确定这两张牌不属于同一个人!没错!这句话表明了要用并查集!
对于每个上述的情况:x=find(a),y=find(b),如果x和y相等说明两者在同一个人手中,那么直接返回false,否则的话我们把他们和另一个的补集相连,p[x]=find(b+n),p[y]=find(a+n)。这代表两者不在同一个集合(因为只有两个集合,所以满足敌人的敌人就是朋友)。
然后对于每个并查集就分给一个人,判断是否会冲突,如果冲突返回false。
如果上述都没有冲突,则返回true。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream> using namespace std;
const int maxn=+;
int n;
int p[maxn];
struct Node{
char s[];
int who;
int num;
}node[maxn];
int ans;
int Wh[maxn],val[maxn];
int find(int x){
return p[x]==x?x:p[x]=find(p[x]);
}
bool check(int A,int B,int C){
for(int i=;i<=;i++)p[i]=i;
memset(Wh,-,sizeof(Wh));
bool ok=;
for(int i=;i<=n;i++){
int a=node[i].s[]-'A'+;
int b=node[i].s[]-'A'+;
int w=node[i].who;
// cout<<a<<" "<<b<<" "<<node[i].num<<endl; if(node[i].num==){
if(a==A||a==B||a==C||b==A||b==B||b==C){
//cout<<"-1"<<endl;
ok=;
break;
}
if((Wh[a]==(w^))||(Wh[b]==(w^))){
ok=;
break;
}
// cout<<-1<<endl;
Wh[a]=w,Wh[b]=w;
}
if(node[i].num==){
if((a==A||a==B||a==C)&&(b==A||b==B||b==C))
continue;
else if(a==A||a==B||a==C){
if(Wh[b]==w){
ok=;
break;
}
Wh[b]=(w^);
}
else if(b==A||b==B||b==C){
if(Wh[a]==w){
ok=;
break;
}
Wh[a]=(w^);
}
else{
if(Wh[a]==w||Wh[b]==w){
ok=;
break;
}
Wh[a]=(w^),Wh[b]=(w^);
}
}
if(node[i].num==){
if((a==A||a==B||a==C)&&(b==A||b==B||b==C)){
ok=;
break;
}
else if(a==A||a==B||a==C){
if(Wh[b]==(w^)){
ok=;
break;
}
Wh[b]=w;
}
else if(b==A||b==B||b==C){
if(Wh[a]==(w^)){
ok=;
break;
}
Wh[a]=w;
}else{
int x=find(a),y=find(b);
if(x==y){
ok=;
break;
}
p[x]=find(b+);
p[y]=find(a+);
}
}
}
if(!ok)return false; memset(val,-,sizeof(val));
for(int i=;i<=;i++){
if(Wh[i]!=-){
int f=find(i);
if(val[f]==
(Wh[i]^)){
ok=;
// cout<<-1<<endl;
break;
}
val[f]=Wh[i];
f=find(i+);
// cout<<Wh[i]<<endl;
if(val[f]==Wh[i]){
// cout<<val[f]<<" "<<Wh[i]<<endl;
ok=;
break;
}
val[f]=(Wh[i]^);
}
}
if(!ok)return false; for(int i=;i<=;i++){
int x=find(i),y=find(i+);
if(x==y||(val[x]==val[y]&&val[x]!=-)){
ok=;
break;
}
}
if(!ok)return false;
return true;
}
int main(){
ans=;
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%s%d%d",node[i].s,&node[i].who,&node[i].num);
node[i].who--;
} for(int i=;i<=;i++){
for(int j=i+;j<=;j++){
for(int k=j+;k<=;k++){
if(check(i,j,k))
ans++;
}
}
}
cout<<ans;
return ;
}
Gym 101128 B Black Vienna的更多相关文章
- GYM 101128 G.Game of Cards(博弈论) 或者 UVALIVE 7278
题目链接:http://codeforces.com/gym/101128/my 如果可以,就看这个人的代码吧,我还不是很懂唉:http://blog.csdn.net/loy_184548/arti ...
- 预处理 Gym - 101128H
题目链接:http://codeforces.com/gym/101128 题目大意:给你一个区间[x,y],找出这个区间有多少个seldom的数字. seldom的数字定义如下:该数值的二进制数字符 ...
- dp+分类讨论 Gym 101128E
题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/detail ...
- 优先队列 逆向思维 Gym 101128C
题目链接:http://codeforces.com/gym/101128/my 具体题目大意可以看这个人的:http://blog.csdn.net/v5zsq/article/details/61 ...
- 很好的脑洞题:dfs+暴力 Gym - 101128A Promotions
http://codeforces.com/gym/101128 题目大意:给你一个a,b,e,p.有e个点,p条有向边,每条边为(x,y),表示x->y,每次我们都取出一个入度为0的,并且一次 ...
- Gym 101128F Sheldon Numbers(网络流)
[题目链接] http://codeforces.com/gym/101128/attachments [题目大意] 给出一张地图,分为高地和低地,高低地的交界线上划有红线, 现在要开小车跨过每条红线 ...
- Southwestern Europe Regional Contest 2015 题解
题目链接:http://codeforces.com/gym/101128 题目数7/10 Rank 34/209 A: 题意:给出一张n个点的有向图表示一家有n个员工的公司的隶属图,u->v表 ...
- 【并查集】Gym - 101128B - Black Vienna
有26张牌(A~Z),其中三张被拿走了.其余23张被分发给了两个人.给你m次调查结果,一次调查结果是对其中一个人询问一对牌,他会告诉你他有这对牌的几张(0~2).问你有多少种被拿走的牌的组合. 三重循 ...
- ACM: Gym 101047M Removing coins in Kem Kadrãn - 暴力
Gym 101047M Removing coins in Kem Kadrãn Time Limit:2000MS Memory Limit:65536KB 64bit IO Fo ...
随机推荐
- auto_ptr, unique_ptr, shared_ptr and weak_ptr智能指针讲解
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...
- PS基础教程[4]如何载入笔刷
笔刷是我们制作图片时的一个很好的工具,能够快速方便的帮助我们制作出很多现有的效果,所以我们都会制作很多的笔刷保存起来载入到PS中方便我们使用.本次系类经验的第四篇就来介绍一下笔刷的导入. 方法 1.笔 ...
- asp.net core microservices 架构之eureka服务发现
一 简介 微服务将需多的功能拆分为许多的轻量级的子应用,这些子应用相互调度.好处就是轻量级,完全符合了敏捷开发的精神.我们知道ut(单元测试),不仅仅提高我们的程序的健壮性,而且可以强制将类和方法的设 ...
- SqlServer2008 新建服务器对象->链接服务器脚本
exec sp_addlinkedserver 'ddxx', '', 'SQLOLEDB','1.192.168.220'exec sp_addlinkedsrvlogin 'ddxx','fa ...
- 谨慎安装Python3.7.0,SSL低版本导致Pip无法使用
最新新配置了一台服务器.安装 的时候直接使用了最新的Python 3.7最新版本. 安装成功,编译成功.但是用pip 安装包的时候提示:pip is configured with locations ...
- photoshop画矩形款
1.屏幕截图 2.在photoshop新建图形 3.用矩形选框 4.右键打开描边,宽度设成5个像素
- 找到div下的第一个ul
$("div#div的id ul li a")//选择的是div下 ul下所有li下的所有a标签 $("div#div的id").children(" ...
- Oracle记录(二) SQLPlus命令
对于Oracle数据库操作主要使用的是命令行方式,而所有的命令都使用sqlplus完成,对于sqlplus有两种形式.就我个人而言,还是比较喜欢UNIX与Linux下的Oracle.呵呵 一种是dos ...
- 获取sonar扫描结果
api通过抓包获取 java 1.get和post方法 package com.tools.httpUtil; import java.io.BufferedReader; import java.i ...
- 第五章 深入class文件结构
一次编译好的class文件是如何到处运行的 5.1 JVM指令集简介 5.1.1 与类相关的指令 5.1.2 方法的定义 5.1.3 属性的定义 5.1.4 其他指令集 5.2 class文件头的表示 ...