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

2018-07-04  本文已影响0人  木鱼_cc

1.比赛介绍

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

3) 比赛评分: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
上一篇下一篇

猜你喜欢

热点阅读