• HDU2094 产生冠军


    产生冠军

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 26594    Accepted Submission(s): 11947

    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

    解题思路:这道题我用了STL容器中的set,就是把所有赢的人的名字存入set容器中,然后用了两个双重循环遍历,如果赢的人中有曾经输过的,就从set中删除,最后判断如果容器大小为

    一就输出yes,否则输出no;

    另外有一个小坑点就是最后要用clear()清理set容器,不然会wa;

    代码如下(AC):

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <set>
    using namespace std;
    set<string> v1;
    int main(){
        string str1[1010],str2[1010];
        int n;
        while(cin>>n,n){
            for(int i=0;i<n;i++){
                cin>>str1[i]>>str2[i];
                v1.insert(str1[i]);
            }
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    if(str1[i]==str2[j])
                    v1.erase(str1[i]);
                }
            }
            if(v1.size()==1) 
            printf("Yes
    ");
            else printf("No
    ");
            v1.clear();
        }
        return 0;
    }

    顺便补一下STL的set容器知识:

    在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。

    set使用方法:

    begin()     ,返回set容器的第一个迭代器

    end()      ,返回set容器的最后一个迭代器

    clear()        ,删除set容器中的所有的元素

    empty()    ,判断set容器是否为空

    max_size()   ,返回set容器可能包含的元素最大个数

    size()      ,返回当前set容器中的元素个数

    rbegin     ,返回的值和end()相同

    rend()     ,返回的值和rbegin()相同


    简单的操作实例:

    #include <iostream>  
    #include <set>  
      
    using namespace std;  
      
    int main()  
    {  
        set<int> s;  
        s.insert(1);  
        s.insert(2);  
        s.insert(3);  
        s.insert(1);  
        cout<<"set 的 size 值为 :"<<s.size()<<endl;  
        cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;  
        cout<<"set 中的第一个元素是 :"<<*s.begin()<<endl;  
        cout<<"set 中的最后一个元素是:"<<*s.end()<<endl;  
        s.clear();  
        if(s.empty())  
        {  
            cout<<"set 为空 !!!"<<endl;  
        }  
        cout<<"set 的 size 值为 :"<<s.size()<<endl;  
        cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;  
        return 0;  
    }

    小结:插入3之后虽然插入了一个1,但是我们发现set中最后一个值仍然是3哈,这就是set 。还要注意begin() 和 end()函数是不检查set是否为空的,使用前最好使用empty()检验一下set是否为空.

    count()方法:

    count() 用来查找set中某个某个键值出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了。

    实例代码:

    #include <iostream>  
    #include <set>  
      
    using namespace std;  
      
    int main()  
    {  
        set<int> s;  
        s.insert(1);  
        s.insert(2);  
        s.insert(3);  
        s.insert(1);  
        cout<<"set 中 1 出现的次数是 :"<<s.count(1)<<endl;  
        cout<<"set 中 4 出现的次数是 :"<<s.count(4)<<endl;  
        return 0;  
    }

    erase()方法:

    erase(iterator)  ,删除定位器iterator指向的值

    erase(first,second),删除定位器first和second之间的值

    erase(key_value),删除键值key_value的值

    #include <iostream>  
    #include <set>  
      
    using namespace std;  
      
    int main()  
    {  
        set<int> s;  
        set<int>::const_iterator iter;  
        set<int>::iterator first;  
        set<int>::iterator second;  
        for(int i = 1 ; i <= 10 ; ++i)  
        {  
            s.insert(i);  
        }  
        //第一种删除  
        s.erase(s.begin());  
        //第二种删除  
        first = s.begin();  
        second = s.begin();  
        second++;  
        second++;  
        s.erase(first,second);  
        //第三种删除  
        s.erase(8);  
        cout<<"删除后 set 中元素是 :";  
        for(iter = s.begin() ; iter != s.end() ; ++iter)  
        {  
            cout<<*iter<<" ";  
        }  
        cout<<endl;  
        return 0;  
    }

    小结:set中的删除操作是不进行任何的错误检查的,比如定位器的是否合法等等,所以用的时候自己一定要注意。

    find()方法:

    find()  ,返回给定值值得定位器,如果没找到则返回end()。

    #include <iostream>
    #include <set>
     
    using namespace std;
     
    int main()
    {
        int a[] = { 4, 6, 2 , 3};
        set<int> s(a,a + 4);
        set<int>::iterator iter;
        for(iter = s.begin();iter != s.end();iter++)
        {
            cout << *iter << "  " ;
        }
        cout << endl;
        if((iter = s.find(2)) != s.end())
            cout<<*iter<<endl;
        if((iter = s.find(1)) != s.end())
            cout<<*iter<<endl;
     
     
        return 0;
    }

    运行结果:

    2 3 4 6

    2

    小结:find(x)是返回的是x的值,如果x没有在set中则会输出end();

    lower_bound(key_value) ,返回第一个大于等于key_value的定位器

    upper_bound(key_value),返回最后一个大于key_value的定位器

    #include <iostream>
    #include <set>
     
    using namespace std;
     
    int main()
    {
        set<int> s;
        for(int i = 1;i <= 5;i ++)
        {
            int x;
            cin >> x;
            s.insert(x);
        }
        set<int>::iterator iter;
        for(iter = s.begin() ; iter != s.end() ; ++iter)
        {
            cout << *iter << " ";
        }
        cout << endl;
        cout << "第一个大于等于 2 的值是:   ";
            cout<<*s.lower_bound(2)<<endl;
        cout << "第一个大于等于 3 的值是:   ";
            cout<<*s.lower_bound(3)<<endl;
        cout << "第一个大于 3 的值是:   ";
            cout<<*s.upper_bound(3)<<endl;
        return 0;
    }
    天晴了,起飞吧
  • 相关阅读:
    iOS 基础类解析
    冒泡排序Vs直接选择排序
    【HDOJ 5419】 Victor and Toys (排列组合)
    我的互联网安全观
    Linux进程间通信-信号量
    AFNetworking 3.0携带參数上传文件Demo
    ANDROID窗体管理服务实现机制和架构分析
    【ODPS】阿里云ODPS中带分区的表操作
    Android自定义组件系列【13】——Android自定义对话框如此简单
    微信支付开发(2) 静态链接Native支付
  • 原文地址:https://www.cnblogs.com/jianqiao123/p/11329908.html
Copyright © 2020-2023  润新知