【并查集】Gym - 101128B - Black Vienna
有26张牌(A~Z),其中三张被拿走了。其余23张被分发给了两个人。给你m次调查结果,一次调查结果是对其中一个人询问一对牌,他会告诉你他有这对牌的几张(0~2)。问你有多少种被拿走的牌的组合。
三重循环枚举被拿走的牌。
然后对于一次调查,我们发现可能的十二种情况中({这两张牌都被拿走,都不被,其中一张被拿走,其中另一张被拿走} × {回答:0,1,2}),只有一种情况我们不能确定它们的归属,或者无解。即两张牌都不被拿走,并且回答是1。那么必然其中一张牌在一个人手上,另一张牌在另一人手上,但我们不能确定是那张。
其实这是个2-sat的XOR。
因为是双向边,我们可以直接用并查集。
然后有些牌的归属在一开始就已经被制定了。
如果A和!A在同一个并查集里边或者其并查集的取值都一开始确定,并且两者相同,那么无解。其他都有解。
#include<cstdio>
#include<cstring>
using namespace std;
int n,whi[55],xs[55],ans;
char op[55][4];
bool cho[105];
int beg[105];
int fa[105],val[105];
int find(int x){
return x==fa[x] ? x : fa[x]=find(fa[x]);
}
int main(){
// freopen("b.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%s%d%d",op[i],&whi[i],&xs[i]);
--whi[i];
}
for(int i='A';i<='Z';++i){
for(int j=i+1;j<='Z';++j){
for(int k=j+1;k<='Z';++k){
memset(beg,-1,sizeof(beg));
memset(val,-1,sizeof(val));
for(int p=1;p<=52;++p){
fa[p]=p;
}
cho[i]=cho[j]=cho[k]=1;
bool flag=1;
for(int p=1;p<=n;++p){
if(cho[op[p][0]] && cho[op[p][1]]){
if(xs[p]>=1){
flag=0;
break;
}
}
else if(cho[op[p][0]]){
if(xs[p]==0){
if(beg[op[p][1]]==whi[p]){
flag=0;
break;
}
beg[op[p][1]]=(whi[p]^1);
}
else if(xs[p]==1){
if(beg[op[p][1]]==(whi[p]^1)){
flag=0;
break;
}
beg[op[p][1]]=whi[p];
}
else{
flag=0;
break;
}
}
else if(cho[op[p][1]]){
if(xs[p]==0){
if(beg[op[p][0]]==whi[p]){
flag=0;
break;
}
beg[op[p][0]]=(whi[p]^1);
}
else if(xs[p]==1){
if(beg[op[p][0]]==(whi[p]^1)){
flag=0;
break;
}
beg[op[p][0]]=whi[p];
}
else{
flag=0;
break;
}
}
else{
if(xs[p]==0){
if(beg[op[p][0]]==whi[p] || beg[op[p][1]]==whi[p]){
flag=0;
break;
}
beg[op[p][0]]=beg[op[p][1]]=(whi[p]^1);
}
else if(xs[p]==2){
if(beg[op[p][0]]==(whi[p]^1) || beg[op[p][1]]==(whi[p]^1)){
flag=0;
break;
}
beg[op[p][0]]=beg[op[p][1]]=whi[p];
}
else{
int f1=find(op[p][0]-'A'+1),f2=find(op[p][1]-'A'+1+26);
fa[f1]=f2;
f1=find(op[p][0]-'A'+1+26),f2=find(op[p][1]-'A'+1);
fa[f2]=f1;
}
}
}
if(flag){
// if(i=='X' && j=='Y' && k=='Z'){
// i='X';
// }
for(int p='A';p<='Z';++p){
if(beg[p]!=-1){
int f=find(p-'A'+1);
if(val[f]==(beg[p]^1)){
flag=0;
break;
}
else{
val[f]=beg[p];
} f=find(p-'A'+1+26);
if(val[f]==beg[p]){
flag=0;
break;
}
else{
val[f]=(beg[p]^1);
}
}
}
if(flag){
for(int p='A';p<='Z';++p){
int f1=find(p-'A'+1),f2=find(p-'A'+1+26);
if(f1==f2 || (val[f1]==val[f2] && val[f1]!=-1)){
flag=0;
break;
}
}
if(flag){
++ans;
}
}
}
cho[i]=cho[j]=cho[k]=0;
}
}
}
printf("%d\n",ans);
return 0;
}
【并查集】Gym - 101128B - Black Vienna的更多相关文章
- Codeforces Gym 100463E Spies 并查集
Spies Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Desc ...
- Gym - 100625G Getting Through 计算几何+并查集
http://codeforces.com/gym/100625/attachments/download/3213/2013-benelux-algorithm-programming-contes ...
- Gym 100814C Connecting Graph 并查集+LCA
Description standard input/output Statements Alex is known to be very clever, but Walter does not be ...
- Tree Restoration Gym - 101755F (并查集)
There is a tree of n vertices. For each vertex a list of all its successors is known (not only direc ...
- GYM 101173 F.Free Figurines(贪心||并查集)
原题链接 题意:俄罗斯套娃,给出一个初始状态和终止状态,问至少需要多少步操作才能实现状态转化 贪心做法如果完全拆掉再重装,答案是p[i]和q[i]中不为0的值的个数.现在要求寻找最小步数,显然要减去一 ...
- Gym - 101243F Vitamins(思维+并查集)
题意 有三种药丸,白色W>红色R>蓝色B,给你m个约束条件,问你n个药丸的颜色,不能确定颜色输出‘?’ 题解 如果1<2<3,只要找到2就能确定1和3的颜色 如果2=4,只要确 ...
- Gym - 101550A Artwork (并查集在线做法)
题目链接 题意:给你一个n*m的网格图,初始时格点全白,每次可以将一段连续的格点涂黑.求出每次操作之后白色连通块的数量. 看了看网上的题解,基本全是离线的做法.其实这道题是有在线的做法的,利用了对偶图 ...
- 【随机化】【并查集】Gym - 100851J - Jump
题意:交互题,有一个长度为n(偶数)的二进制串,你需要猜不超过n+500次猜到它.如果你猜的串与原串相同的位数为n,那么会返回n,如果为n/2,那么会返回n/2,否则都会返回零. 先random,直到 ...
- 【枚举】【并查集】Gym - 101243F - Vitamins
题意:有n片药,有三种颜色,白色比红色重,红色比蓝色重,给你一些它们之间的重量关系,比如1>3,2=4之类,问你它们的颜色,如果没法判断的输出?. 先并查集把等于号全缩起来,然后按照大于号建图, ...
随机推荐
- solaris 服务器配置网络
1. 修改配置文件 vi /etc/hostname.e1000g1 --e1000g1是硬件(网卡)的名称,不同的服务器名称不同 添加/修改:192.168.50.238 ...
- Android Studio 中引入Library
启动AndroidStudio后,打开你需要接收Library的项目.比如有两个项目,项目A,和Library项目B,那么打开项目A.图中所示为项目的结构图,点击右上角的File菜单. 2 在下拉菜单 ...
- js中的true和false
1.false undefined.NaN.0.null和空字符串''均被视为false 2.true 除上述以外的其它情况一律被视作true
- .net爬虫了解一下
using System; //添加selenium的引用 using OpenQA.Selenium.PhantomJS; using OpenQA.Selenium.Chrome; using O ...
- BZOJ 4241: 历史研究——莫队 二叉堆
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4241 题意:N个int范围内的数,M次询问一个区间最大的(数字*出现次数)(加权众数),可以 ...
- 设计模式之笔记--适配器模式(Adapter)
适配器模式(Adapter) 定义 适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 适配器模式 ...
- JS函数和变量名称冲突
在JS中如果函数名与变量名冲突,JS是怎么执行的? <script> console.log(sum);//function sum(){} function sum(){} var su ...
- 【python】pymongo中正则查询时的转义问题
在查询mongo时用到了正则查询 设字符串为 str = '/ab/cd.ef?g=' 直接用正则查询没有匹配. collection.find({"re":{'$regex' ...
- mysql 主从 同步原理及配置
一.在mssql 里头实现同步镜像,只能主库用而镜像库不能同时用,而mysql 主从同步可以实现 数据库的读写分离,主库负责 update insert delete ,从库负责select 这样一来 ...
- SGU 263. Towers
各种操作: put x c:表示在第 x 列上增加 c 个积木(c>0). tput t x c:表示在塔 t 的第 x 列上增加 c 个积木(c>0). towers:询问共有几座塔. ...