题意

有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. [QT]安装中出现的问题(安装qt5.8,出现Could not start:"{0,3010,1603,5100} msiexec ...")

    安装环境:win7/10 qt版本: qt-opensource-windows-x86-mingw530-5.8.0 在两台电脑上安装到 qt.tool.perl 的时候就弹出如图的窗口错误,开始以 ...

  2. c++11新特性之宽窄字符转换

    C++11增加了unicode字面量的支持,可以通过L来定义宽字符:str::wstring str = L"中国人": 将宽字符转换为窄字符串需要用到codecvt库中的std: ...

  3. bzoj 1220 跳蚤

    Written with StackEdit. Description \(Z\)城市居住着很多只跳蚤.在\(Z\)城市周六生活频道有一个娱乐节目.一只跳蚤将被请上一个高空钢丝的正中央.钢丝很长,可以 ...

  4. HTTP Status 500 - Error instantiating servlet class XXXX

    问题描述 web项目中请求出现错误,如下:  HTTP Status 500 - Error instantiating servlet class XXXX类  type Exception rep ...

  5. 【转】C# Socket编程(2)识别网络主机

    [转自:https://www.cnblogs.com/IPrograming/archive/2012/10/11/CSharp_Socket_2.html] 一个客户端想要发起一次通信,先决条件就 ...

  6. POJ3764,BZOJ1954 The xor-longest Path

    题意 In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of ...

  7. Vue脚手架搭建过程

    1.使用npm全局安装vue-cli(前提是你已经安装了nodejs,否则你连npm都用不了),在cmd中输入一下命令 npm install --global vue-cli 安装完成后,创建自己的 ...

  8. c#同步調用異步(async)方法【記錄用】

    使用RestSharp中的異步方法ExecuteTaskAsync<T>編寫寫了一個異步方法,功能很簡單:異步調用API,返回結果,假設為GetAccessToken,方法簽名假設如下: ...

  9. C#网络编程(同步传输字符串) - Part.2

    服务端客户端通信 在与服务端的连接建立以后,我们就可以通过此连接来发送和接收数据.端口与端口之间以流(Stream)的形式传输数据,因为几乎任何对象都可以保存到流中,所以实际上可以在客户端与服务端之间 ...

  10. 10 结构体和类 - —— 《Swift3.0 从入门到出家》

    Swift中的面向对象5个要素:枚举.结构体.类.协议.扩展 面向对象研究的是对象,完成一件事情需要多个对象参与,是生活的映射 Swift中结构体和类非常相似,也就是结构体能完成类的所有功能.结构体是 ...