zoukankan      html  css  js  c++  java
  • 题解报告:hdu 2094 产生冠军

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2094

    Problem Description
    有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。 球赛的规则如下: 如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。 如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。 根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。
    Input
    输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。如果n为0,则表示输入结束。
    Output
    对于每个选手群,若你判断出产生了冠军,则在一行中输出“Yes”,否则在一行中输出“No”。
    Sample Input
    3
    Alice Bob
    Smith John
    Alice Smith
    5
    a c
    c d
    d e
    b e
    a d
    0
    Sample Output
    Yes
    No
    解题思路:这道题要知道的是冠军只有一个,题目的意思可能会使人想到另外的一些解法,比如并查集等等,但其实并不用这么复杂,用C++里面的set容器,其特点是容器元素具有唯一性,即去重。一个用来保存所有选手的名字,一个用来保存所有失败的选手,set1容器大小-set2容器大小==1时,即产生唯一的冠军,否则没有冠军。这里提供两种解法,一种是STL里的set容器,另一种是C语言解法。
    AC代码:
    解法一:C语言解法。二维数组模拟set容器。mark数组用来标记胜利与失败情况。
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int main()
     4 {
     5     int n,i,mark[1005],sum; //n对选手,mark数组来标记胜利和失败
     6     char a[1005][20],b[20],c[20];//二维数组a模拟STL中set容器集合,元素具有唯一性,b打败c
     7     bool fb,fc;//标记当前输入的b和c字符串是否出现过
     8     while(cin>>n && n){
     9         getchar();//吃掉回车符
    10         sum=i=0;
    11         memset(mark,-1,sizeof(mark)); //全部初始化为-1,-1表示为冠军
    12         memset(a,0,sizeof(a));//a数组全部初始化为0
    13         while (n--){ //n对选手
    14             fb=fc=false; //标记为假
    15             cin>>b>>c;
    16             if(i==0){//处理第一对选手
    17                 strcpy(a[i++],b);//先把b,c分别赋值给a数组
    18                 strcpy(a[i++],c);
    19                 mark[i-1]=0; //c对应下标标记存c字符串的结果为0,表示输
    20             }
    21             else{//处理除第一对选手之外的选手情况
    22                 for(int j=0;j<i;j++){//循环到i-1即可,判断以前是否出现过
    23                     if(strcmp(a[j],b)==0)fb = true;//标记b出现过
    24                     if(strcmp(a[j],c)==0){//比较c
    25                         mark[j]=0; //有的话顺便将其置为0,因为是输
    26                         fc=true;  //同时标记出现过
    27                     }
    28                 }
    29                 if(!fb)strcpy(a[i++],b);//没出现的话,还得赋值给a数组
    30                 if(!fc){
    31                     strcpy(a[i++],c);//赋值给a数组之后还得让对应的标记为0
    32                     mark[i-1]=0;
    33                 }
    34             }
    35         }
    36         for(int j=0;j<i;j++)
    37             if (mark[j]==-1)sum++;//统计mark数组胜利的人数
    38         if (sum!=1)cout<<"No"<<endl;//没有冠军
    39         else cout<<"Yes"<<endl; //产生冠军
    40     }
    41     return 0;
    42 }

    解法二:使用STL中的set容器。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int main()
     4 {
     5     int n;
     6     string a,b;
     7     set<string> all;//保存所有选手的名字
     8     set<string> lose;//保存被打败的选手名字
     9     while(cin>>n && n){
    10         all.clear();//每次输入选手群时清空两个容器
    11         lose.clear();
    12         while(n--){
    13             cin>>a>>b;
    14             all.insert(a);//将两个选手名字都插入到all容器中
    15             all.insert(b);
    16             lose.insert(b);//失败的选手名字则插入到lose容器中
    17         }
    18         if(all.size()-lose.size()==1)//当所有选手人数和与被打败选手人数和的差为1时,将产生冠军
    19             cout<<"Yes"<<endl;
    20         else//否则没有冠军
    21             cout<<"No"<<endl;
    22     }
    23     return 0;
    24 }
  • 相关阅读:
    JavaWeb--HttpSession案例
    codeforces B. Balls Game 解题报告
    hdu 1711 Number Sequence 解题报告
    codeforces B. Online Meeting 解题报告
    ZOJ 3706 Break Standard Weight 解题报告
    codeforces C. Magic Formulas 解题报告
    codeforces B. Sereja and Mirroring 解题报告
    zoj 1109 Language of FatMouse 解题报告
    hdu 1361.Parencodings 解题报告
    hdu 1004 Let the Balloon Rise 解题报告
  • 原文地址:https://www.cnblogs.com/acgoto/p/8729175.html
Copyright © 2011-2022 走看看