美文网首页
十、STL综合案例——学校演讲比赛

十、STL综合案例——学校演讲比赛

作者: 木鱼_cc | 来源:发表于2018-07-04 16:42 被阅读0次

    1.比赛介绍

    1) 某市举行一场演讲比赛(speech_contest),共有24人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛
    2) 比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛;

    • 第一轮分为4个小组,每组6人。比如100-105一组,106-111二组,一次类推
    • 没人分别按照抽签(draw)顺序演讲。当小组演讲完后,淘汰组内排名最后的三名宣说,然后进行下一个小组的比赛
    • 第二轮分为2个小组,每组6人。比赛完毕,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
    • 第三轮只剩下6个人,本轮为决赛,选出前三名

    3) 比赛评分:10个评委打分,去除最低、最高分,求平均分

    • 每个选手演讲完由10名评委打分。该选手的最终得分是去掉一个最高分和一个最低分
    • 选手的名字按得分降序排列,若得分一样,按参赛号升序排名

    4) 用STL编程,求解这个问题

    • 请打印出所有选手的名字和参赛号,并以参赛号的升序排列
    • 打印每一轮比赛后,小组比赛成绩和小组晋级名单
    • 打印决赛前三名,选手名称、成绩

    2.需求分析

    //产生选手(ABCDEFGHIJKLMNOPQRSTUVWXYZ) 姓名、得分;选手编号
    //第一轮 选手抽签 选手比赛 查看比赛结果
    //第二轮 选手抽签 选手比赛 查看比赛结果
    //第三轮 选手抽签 选手比赛 查看比赛结果

    3. 实现思路

    需要把选手信息,选手得分信息、选手比赛抽签信息、选手的晋级信息保存到容器中,需要涉及各个容器的类型。(相当于信息的数据库E-R图设计)
    选手可以设计一个 Speaker(姓名和得分)
    所有选手编号和选手信息,可以放在容器内:map<int,Speaker>
    所有选手的编号信息,可以放在容器:vector<int> v1
    第1轮晋级名单,可以放在容器vector<int> v2
    第2轮晋级名单,可以放在容器vector<int> v3
    第3轮晋级名单,可以放在容器vector<int> v4

    每个小组的比赛得分信息,按照从小到大排序放在
    multimap<成绩,编号,greater<int>>multimapGroup
    也就是
    multimap<int,int,greater<int>>multimapGroup
    每个选手的得分,可以放在容器deque<int>dscore;方便去除最低最高分

    4.搭建框架

    #include <iostream>
    #include <map>
    #include <string>
    #include <vector>
    using namespace std;
    
    //定义选手类
    class Speaker{
    public:
        string name;
        int score[3];//保存3轮最终得分
    };
    
    //创建选手
    void Create_Speaker(map<int,Speaker> &mapSpeaker,vector<int> &v1){
        
    }
    
    //选手抽签
    int Random_SpeakerID(vector<int> &v1){
       
    }
    
    
    //选手比赛(第几轮,选手编号,比赛得分保存,晋级编号保存)
    void Match_Speaker(int index,vector<int> &v1,map<int,Speaker> &mapSpeaker,vector<int> &v2){
    
    }
    
    //查看比赛结果(第一轮,结果保存容器,对应名字)   其实就是第一轮结果保存在了v2中,再利用mapSpeaker看名字
    void Show_Match_Result(int index,vector<int> &v2,map<int,Speaker> &mapSpeaker){
    
    }
    
    int main(){
    
     
       map<int,Speaker> mapSpeaker;//保存选手信息 根据编号
    
       vector<int> v1;//保存第一轮参赛的编号
       vector<int> v2;//第一轮比赛的晋级编号(第二轮比赛编号)
       vector<int> v3;//第二轮晋级编号(第三名比赛编号)
       vector<int> v4;//最终最终的前三名编号
    
       //创建选手 24 名
       Create_Speaker(mapSpeaker,v1);
    
       //----------------------------第一轮比赛
    
       //选手抽签
       Random_SpeakerID(v1);//相当于把容器内的编号打乱就好了
    
       //选手比赛 (第一轮,选手,比赛得分保存,编号保存)
       Match_Speaker(1,v1,mapSpeaker,v2);
    
       //查看比赛结果(第一轮,结果保存容器,对应名字)   其实就是第一轮结果保存在了v2中,再利用mapSpeaker看名字
       Show_Match_Result(1,v2,mapSpeaker);
    
    
       //----------------------------第二轮比赛
       Random_SpeakerID(v2);//选手抽签
       Match_Speaker(2,v2,mapSpeaker,v3);//选手比赛
       Show_Match_Result(2,v3,mapSpeaker); //查看比赛结果
    
    
       //----------------------------第三轮比赛
       Random_SpeakerID(v3);//选手抽签
       Match_Speaker(3,v3,mapSpeaker,v4);//选手比赛
       Show_Match_Result(3,v4,mapSpeaker); //查看比赛结果
    
       return 0;
    }
    

    5.完整代码

    #include <iostream>
    #include <map>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <deque>
    #include <numeric>
    #include <functional>
    using namespace std;
    
    //定义选手类
    class Speaker{
    public:
        string name;
        int score[3];//保存3轮最终得分
    };
    
    //创建选手
    void Create_Speaker(map<int,Speaker> &mapSpeaker,vector<int> &v1){
        string nameseed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        for(int i = 0; i < 24;i++){
    
            //创建选手对象
            Speaker speaker;
            speaker.name = "选手";
            speaker.name += nameseed[i];
    
            speaker.score[0] = 0;
            speaker.score[1] = 0;
            speaker.score[2] = 0;
    
    
            //创建选手唯一的参赛编号
            int SpeakerID = 100 + i;
            mapSpeaker.insert(make_pair<int,Speaker>(SpeakerID,speaker));//保存选手信息
            v1.push_back(SpeakerID);
        }
    }
    
    //选手抽签
    int Random_SpeakerID(vector<int> &v1){
       random_shuffle(v1.begin(),v1.end());//在<algorithm>中
    }
    
    //选手比赛(第几轮,选手编号,比赛得分保存,晋级编号保存)
    void Match_Speaker(int index,vector<int> &v1,map<int,Speaker> &mapSpeaker,vector<int> &v2){
        multimap<int,int,greater<int>> mapGroup;//分数做key,id做value 就可以排序了
        int indexTemp = 0;
        int indexGroup = 0;//记录哪一组
        for(vector<int>::iterator it = v1.begin();it != v1.end();it++){
    
            indexTemp++;
            deque<int> dscore;//保存评委10次得分
            for (int i = 0; i < 10; ++i){
                int score = 50 + rand() % 50;
                dscore.push_back(score);
            }
    
            //排序
            sort(dscore.begin(),dscore.end());//从小到大
    
            //去除最高分
            dscore.pop_back();//去除最高分
            dscore.pop_front();//去除最低分
    
            //求平均分 先累加
            int totalscore = accumulate(dscore.begin(),dscore.end(),0);//在numeric中
            int scoreavg = totalscore/dscore.size();
    
            mapSpeaker[*it].score[index-1] = scoreavg;//*it就是编号 index-1才是分数
            
            mapGroup.insert(make_pair<int,int>(scoreavg,*it));//保存分组信息
    
            if (indexTemp % 6 == 0)
            {
                indexGroup++;
                int highIndex = 0;
                printf("第%d轮比赛成绩第%d组比赛成绩:\n",index,indexGroup);
                for(multimap<int,int,greater<int>>::iterator it2 = mapGroup.begin();it2 != mapGroup.end();it2++){
                      highIndex++;
                      if (highIndex <= 3)
                      {
                        v2.push_back(it2->second);//保存前三名
                      }
                      cout<<"姓名:"<<mapSpeaker[it2->second].name<<" 分数:"<<mapSpeaker[it2->second].score[index-1]<<endl;
                }
    
                mapGroup.clear();//清空mapGroup
            }
    
        }
    }
    
    //查看比赛结果(第一轮,结果保存容器,对应名字)   其实就是第一轮结果保存在了v2中,再利用mapSpeaker看名字
    void Show_Match_Result(int index,vector<int> &v2,map<int,Speaker> &mapSpeaker){
    
       printf("第%d轮比赛晋级名单\n",index);
       for(vector<int>::iterator it = v2.begin();it != v2.end();it++){
           cout<<"姓名:"<<mapSpeaker[*it].name<<" 分数"<<mapSpeaker[*it].score[index-1]<<endl;
       }
    }
    
    int main(){
    
     
       map<int,Speaker> mapSpeaker;//保存选手信息 根据编号
    
       vector<int> v1;//保存第一轮参赛的编号
       vector<int> v2;//第一轮比赛的晋级编号(第二轮比赛编号)
       vector<int> v3;//第二轮晋级编号(第三名比赛编号)
       vector<int> v4;//最终最终的前三名编号
    
       //创建选手 24 名
       Create_Speaker(mapSpeaker,v1);
    
       //----------------------------第一轮比赛
    
       //选手抽签
       Random_SpeakerID(v1);//相当于把容器内的编号打乱就好了
    
       //选手比赛 (第一轮,选手,比赛得分保存,编号保存)
       Match_Speaker(1,v1,mapSpeaker,v2);
    
       //查看比赛结果(第一轮,结果保存容器,对应名字)   其实就是第一轮结果保存在了v2中,再利用mapSpeaker看名字
       Show_Match_Result(1,v2,mapSpeaker);
    
    
       //----------------------------第二轮比赛
       Random_SpeakerID(v2);//选手抽签
       Match_Speaker(2,v2,mapSpeaker,v3);//选手比赛
       Show_Match_Result(2,v3,mapSpeaker); //查看比赛结果
    
    
       //----------------------------第三轮比赛
       Random_SpeakerID(v3);//选手抽签
       Match_Speaker(3,v3,mapSpeaker,v4);//选手比赛
       Show_Match_Result(3,v4,mapSpeaker); //查看比赛结果
    
       return 0;
    }
    
    1.png

    相关文章

      网友评论

          本文标题:十、STL综合案例——学校演讲比赛

          本文链接:https://www.haomeiwen.com/subject/scveuftx.html