题意

有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的更多相关文章

  1. GYM 101128 G.Game of Cards(博弈论) 或者 UVALIVE 7278

    题目链接:http://codeforces.com/gym/101128/my 如果可以,就看这个人的代码吧,我还不是很懂唉:http://blog.csdn.net/loy_184548/arti ...

  2. 预处理 Gym - 101128H

    题目链接:http://codeforces.com/gym/101128 题目大意:给你一个区间[x,y],找出这个区间有多少个seldom的数字. seldom的数字定义如下:该数值的二进制数字符 ...

  3. dp+分类讨论 Gym 101128E

    题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/detail ...

  4. 优先队列 逆向思维 Gym 101128C

    题目链接:http://codeforces.com/gym/101128/my 具体题目大意可以看这个人的:http://blog.csdn.net/v5zsq/article/details/61 ...

  5. 很好的脑洞题:dfs+暴力 Gym - 101128A Promotions

    http://codeforces.com/gym/101128 题目大意:给你一个a,b,e,p.有e个点,p条有向边,每条边为(x,y),表示x->y,每次我们都取出一个入度为0的,并且一次 ...

  6. Gym 101128F Sheldon Numbers(网络流)

    [题目链接] http://codeforces.com/gym/101128/attachments [题目大意] 给出一张地图,分为高地和低地,高低地的交界线上划有红线, 现在要开小车跨过每条红线 ...

  7. Southwestern Europe Regional Contest 2015 题解

    题目链接:http://codeforces.com/gym/101128 题目数7/10 Rank 34/209 A: 题意:给出一张n个点的有向图表示一家有n个员工的公司的隶属图,u->v表 ...

  8. 【并查集】Gym - 101128B - Black Vienna

    有26张牌(A~Z),其中三张被拿走了.其余23张被分发给了两个人.给你m次调查结果,一次调查结果是对其中一个人询问一对牌,他会告诉你他有这对牌的几张(0~2).问你有多少种被拿走的牌的组合. 三重循 ...

  9. 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 ...

随机推荐

  1. 【MFC】picture控件 两种有细微差别的动态加载图片方法

    摘自:http://www.jizhuomi.com/software/193.html VS2010/MFC编程入门之二十七(常用控件:图片控件Picture Control) 分类标签: 编程入门 ...

  2. linux中的vim编辑器的使用

    vim的三种模式: 常规模式(命令模式)也是默认模式,从其它模式进行命令模式按esc i 在光标前插入文本 o 命令是指在当前行下方插入新行 dd 是删除光标所在的整个一行 yy 是在光标所在整个放入 ...

  3. Oracle 索引的失效和重建

    查询指定表的索引 SELECT T1.TABLE_NAME, T1.INDEX_NAME, T1.INDEX_TYPE, T1.UNIQUENESS, T1.TABLE_OWNER, T1.STATU ...

  4. CentOS下安装w3m,及w3m的使用

    centos下安装软件的命令不是apt-get,而是yum,如果安装w3m,利用sudo yum install w3m w3m-img -y即可 △△△△△△△△如果你用的是centos或readh ...

  5. Consul做服务发现

    使用Consul做服务发现的若干姿势 https://www.cnblogs.com/bossma/p/9756809.html 从2016年起就开始接触Consul,使用的主要目的就是做服务发现,后 ...

  6. rabbitmq java

    package com.enniu.rabbitmq; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.AMQP.BasicPr ...

  7. FastAdmin 将 PHP 框架升级到 ThinkPHP 5.1

    FastAdmin 将 PHP 框架升级到 ThinkPHP 5.1 社区经常有人问什么时候升级到 ThinkPHP 5.1,但是 ThinkPHP 5.1 和 ThinkPHP 5.0 差别非常大, ...

  8. Voting and Shuffling to Optimize Atomic Operations

    2iSome years ago I started work on my first CUDA implementation of the Multiparticle Collision Dynam ...

  9. 终端启动tomcat报错 command not found 解决方法 (含启动和关闭命令)

    Tomcat配置步骤: 1.cd命令进入Tomcat安装路径的bin下 2.sudo chmod 755*.sh 输入appleID密码获得相关权限 3.sudo sh ./startup.sh启动T ...

  10. 事务之三:编程式事务、声明式事务(XML配置事务、注解实现事务)

    Spring2.0框架的事务处理有两大类: JdbcTemplate操作采用的是JDBC默认的AutoCommit模式,也就是说我们还无法保证数据操作的原子性(要么全部生效,要么全部无效),如: Jd ...