zoukankan      html  css  js  c++  java
  • HDU2094(产生冠军)题解

    HDU2094(产生冠军)题解

    以防万一,题目原文和链接均附在文末。那么先是题目分析:

    【一句话题意】

    根据给定现有比赛结果推断分析冠军。(这描述...我建议还是看题吧,题不长)

    【题目分析】

    给出的数据是每两个选手之间的关♂系,于是以为是简单链表,后来感觉是并查集,再后来才发现都不科学。于是换了一个特别科学普通简单粗暴可爱的方法。
    在说方法之前,我想吐槽几句。这道题似乎不够严谨。数据里如果有一组是a>b;b>c;c>a;d>e的话,这将分为两个不相关的组合。这种情况我感觉应该输出的是No(两组人之前根本没有比赛,没办法知道d是不是可以打败abc成为冠军)。而实际上输出的是Yes。所以。。。。。。。。感觉不科学吧。。

    【算法流程】

    列名单,塞人员:
    实际上就是把所有人名都列出来,从来没赢过的摔倒,赢过并且输过的摔掉。剩下的如果只有一个那就是冠军,如果不止一个就不是了。
    简单优化:
    与其列出所有人名然后筛选出赢过的,还不如直接只给赢过的列表。那么我们需要两个表,一个放赢家(只要赢过都算),一个放输家(只要输过的就算)。接下来拿赢家中的每一个对象在输家中找,如果找到就可以摔掉了。最后剩下的就是超级大赢家了。当然,为了去重,我们选择使用STL容器中的set集合处理去重。
    STL:SET(std::set):

    • 初始化创建:set<string> loserList;
    • 清空元素:loserList.clear();
    • 在集合中插入:loserList.insert(loser);
    • 查找在集合中是否存在:loserList.find(*winnerIter)==loserList.end()//则不存在

    这些东西列出来供尚未接触STL的人参考
    从未接触过std::set的话,更多相关参见http://www.cplusplus.com/reference/set/set/
    从未接触过STL的话,请复习cpp。

    #include <iostream> 
    #include <string>
    #include <algorithm>
    #include <set>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    #define each(i,n) (int i=1;i<=(n);++i)
    
    using namespace std;
    
    int main() {
        
        set<string> winnerList;
        set<string> loserList;
        string winner,loser;
        int dataCount, flag;
        
        while(scanf("%d",&dataCount)!=EOF){
            if (dataCount == 0) break;
            winnerList.clear();
            loserList.clear();
            while(dataCount--){
                cin>>winner>>loser;
                winnerList.insert(winner);
                loserList.insert(loser);
            }
            flag = 0;
            set<string>::iterator winnerIter=winnerList.begin();
            for(;winnerIter!=winnerList.end();winnerIter++) {
                if (loserList.find(*winnerIter)==loserList.end()){
                    //cout<<"["<<*winnerIter<<endl;本来以为需要输出赢家是谁呢。。。
                    ++flag;
                    //break;
                }
            }
            if (flag == 1) {
                cout<<"Yes"<<endl;
            } else {
                cout<<"No"<<endl;
            }
        }
    } 
    /*
    TestData(IN)
    3
    Alice Bob
    Smith John
    Alice Smith
    5
    a c
    c d
    d e
    b e
    a d
    0
    TestData(OUT)
    Yes
    No
    */

    题目链接:(HDU 2094)产生冠军

    题目属性:脑筋急转弯(有说是并查集的,还有说是拓扑排序的,我刚开始还以为是单链表,嘛,管他呢。。),STL应用练习(可以当应用练习吧。。)
    相关题目:1342、1361、1370、1506、1577、1597、1702、1716、1727(并非都是脑筋急转弯)
    题目原文:
    【Desc】有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。
    球赛的规则如下:
    如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。
    如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。
    根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。
    【In】输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。如果n为0,则表示输入结束。
    【Out】输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。如果n为0,则表示输入结束。
    【SampIn/Out】参见代码下方的注释。

  • 相关阅读:
    Cocos2dx for Windows Phone 8 发布
    Tiny Core Linux 4.7 发布
    走进 Google 的 Go 语言
    XCache 3.0.0 发布,PHP 性能提升方案
    Entropy Broker 2.0 发布,加密安全随机数
    Windows Phone 8 同步工具已提供,功能对比表
    PolarSSL 1.2.0 发布,SSL 加密库
    YUI 2 存在SWF漏洞,YUI 3 不受影响
    Google改进Dart并提供SDK
    Expression Blend实例中文教程(3) 布局控件快速入门Grid
  • 原文地址:https://www.cnblogs.com/blumia/p/hdu2094.html
Copyright © 2011-2022 走看看