zoukankan      html  css  js  c++  java
  • 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。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <iostream>
      5 
      6 using namespace std;
      7 const int maxn=100+10;
      8 int n;
      9 int p[maxn];
     10 struct Node{
     11     char s[2];
     12     int who;
     13     int num;
     14 }node[maxn];
     15 int ans;
     16 int Wh[maxn],val[maxn];
     17 int find(int x){
     18     return p[x]==x?x:p[x]=find(p[x]);
     19 }
     20 bool check(int A,int B,int C){
     21     for(int i=1;i<=60;i++)p[i]=i;
     22     memset(Wh,-1,sizeof(Wh));
     23     bool ok=1;
     24     for(int i=1;i<=n;i++){
     25         int a=node[i].s[0]-'A'+1;
     26         int b=node[i].s[1]-'A'+1;
     27         int w=node[i].who;
     28       //  cout<<a<<" "<<b<<" "<<node[i].num<<endl;
     29 
     30         if(node[i].num==2){
     31             if(a==A||a==B||a==C||b==A||b==B||b==C){
     32                 //cout<<"-1"<<endl;
     33                 ok=0;
     34                 break;
     35             }
     36             if((Wh[a]==(w^1))||(Wh[b]==(w^1))){
     37                 ok=0;
     38                 break;
     39             }
     40            // cout<<-1<<endl;
     41             Wh[a]=w,Wh[b]=w;
     42         }
     43         if(node[i].num==0){
     44             if((a==A||a==B||a==C)&&(b==A||b==B||b==C))
     45                 continue;
     46             else if(a==A||a==B||a==C){
     47                 if(Wh[b]==w){
     48                     ok=0;
     49                     break;
     50                 }
     51                 Wh[b]=(w^1);
     52             }
     53             else if(b==A||b==B||b==C){
     54                 if(Wh[a]==w){
     55                     ok=0;
     56                     break;
     57                 }
     58                 Wh[a]=(w^1);
     59             }
     60             else{
     61                 if(Wh[a]==w||Wh[b]==w){
     62                     ok=0;
     63                     break;
     64                 }
     65                 Wh[a]=(w^1),Wh[b]=(w^1);
     66             }
     67         }
     68         if(node[i].num==1){
     69             if((a==A||a==B||a==C)&&(b==A||b==B||b==C)){
     70                 ok=0;
     71                 break;
     72             }
     73             else if(a==A||a==B||a==C){
     74                 if(Wh[b]==(w^1)){
     75                     ok=0;
     76                     break;
     77                 }
     78                 Wh[b]=w;
     79             }
     80             else if(b==A||b==B||b==C){
     81                 if(Wh[a]==(w^1)){
     82                     ok=0;
     83                     break;
     84                 }
     85                 Wh[a]=w;
     86             }else{
     87                 int x=find(a),y=find(b);
     88                 if(x==y){
     89                     ok=0;
     90                     break;
     91                 }
     92                 p[x]=find(b+26);
     93                 p[y]=find(a+26);
     94             }
     95         }
     96     }
     97     if(!ok)return false;
     98 
     99     memset(val,-1,sizeof(val));
    100     for(int i=1;i<=26;i++){
    101         if(Wh[i]!=-1){
    102             int f=find(i);
    103             if(val[f]==
    104                (Wh[i]^1)){
    105                 ok=0;
    106               //  cout<<-1<<endl;
    107                 break;
    108             }
    109             val[f]=Wh[i];
    110             f=find(i+26);
    111            // cout<<Wh[i]<<endl;
    112             if(val[f]==Wh[i]){
    113                // cout<<val[f]<<" "<<Wh[i]<<endl;
    114                 ok=0;
    115                 break;
    116             }
    117             val[f]=(Wh[i]^1);
    118         }
    119     }
    120     if(!ok)return false;
    121 
    122     for(int i=1;i<=26;i++){
    123         int x=find(i),y=find(i+26);
    124         if(x==y||(val[x]==val[y]&&val[x]!=-1)){
    125             ok=0;
    126             break;
    127         }
    128     }
    129     if(!ok)return false;
    130     return true;
    131 }
    132 int main(){
    133     ans=0;
    134     scanf("%d",&n);
    135     for(int i=1;i<=n;i++){
    136         scanf("%s%d%d",node[i].s,&node[i].who,&node[i].num);
    137         node[i].who--;
    138     }
    139 
    140     for(int i=1;i<=26;i++){
    141         for(int j=i+1;j<=26;j++){
    142             for(int k=j+1;k<=26;k++){
    143                 if(check(i,j,k))
    144                     ans++;
    145             }
    146         }
    147     }
    148     cout<<ans;
    149 return 0;
    150 }
    View Code
  • 相关阅读:
    RUST实践.md
    redis.md
    opencvrust.md
    aws rds can't connect to mysql server on 'xx'
    Foundation ActionScript 3.0 With Flash CS3 And Flex
    Foundation Flash Applications for Mobile Devices
    Flash Mobile Developing Android and iOS Applications
    Flash Game Development by Example
    Actionscript 3.0 迁移指南
    在SWT中非UI线程控制界面
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/8824803.html
Copyright © 2011-2022 走看看