六、STL之案例练习
一、演讲比赛,评委打分
1.1 比赛规则
某市举行一场演讲比赛( speech_contest ),共有24个人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛。
比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛;
第一轮分为4个小组,每组6个人。比如编号为: 100-123. 整体进行抽签(draw)后顺序演讲。当小组演讲完后,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
第二轮分为2个小组,每组6人。比赛完毕,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
第三轮只剩下1组6个人,本轮为决赛,选出前三名。
比赛评分:10个评委打分,去除最低、最高分,求平均分每个选手演讲完由10个评委分别打分。该选手的最终得分是去掉一个最高分和一个最低分,求得剩下的8个成绩的平均分。选手的名次按得分降序排列。
1.2 需求分析
1) 产生选手 ( ABCDEFGHIJKLMNOPQRSTUVWX ) 姓名、得分;选手编号
2) 第1轮 选手抽签 选手比赛 查看比赛结果
3) 第2轮 选手抽签 选手比赛 查看比赛结果
4) 第3轮 选手抽签 选手比赛 查看比赛结果
1.3 实现思路
需要把选手信息、选手得分信息、选手比赛抽签信息、选手的晋级信息保存在容器中,需要涉及到各个容器的选型。
选手可以设计一个类Speaker(姓名和得分)
所有选手的编号可以单独放在一个vector容器中,做抽签用
所有选手编号和选手信息,可以放在容器内:map<int, Speaker>
所有选手的编号名单,可以放在容器:vecter<int> v1中
第1轮晋级编号名单,可以放在容器vecter<int> v2中
第2轮晋级编号名单,可以放在容器vecter<int> v3中
第3轮前三名名单,可以放在容器vecter<int> v4中
每个小组的比赛得分信息,按照从大到小的顺序放在multimap<成绩, 编号, greater<int>>中
个选手的得分,可以放在容器deque<int> dscore; 方便去除最低最高分.
1.4 代码总结
#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<string> #include<vector> #include<algorithm> #include<iterator> #include<map> #include<deque> #include<numeric> #include<functional> #include<ctime> using namespace std; class Speaker { public: string Name; // 姓名 int Score[3]; // 得分, 三轮得分 }; // . 创建选手 void createSpeaker(vector<int> &v, map<int, Speaker> &m) { string nameSeed = "ABCDEFGHIJKLMNOPQRSTUVWX"; for (int i = 0; i < 24; i++) { string name = "选手"; name = name + nameSeed[i]; Speaker sp; sp.Name = name; sp.Score[0] = 0; // 存选手编号 v.push_back(i + 100); // m存放编号和对应的选手 m.insert(make_pair(i + 100, sp)); } } // 抽签, 打乱顺序 void speechDraw(vector<int> &v) { random_shuffle(v.begin(), v.end()); } // 选手比赛 参数1: 比赛轮数, 参数2: 比赛人员编号, 参数3: 人员编号和具体的人员信息, 参数4: 晋级的人员的编号 void speechContest(int index, vector<int> &v, map<int, Speaker> &m, vector<int> &v2) { int num = 0; // 创建临时容器, 存放小组的人员信息, key代表分数, value代表编号, greater代表排序规则 multimap<int, int, greater<int>> mGroup; for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { num++; // deque 存放评委打分 deque<int> d; for (int i = 0; i < 10; i++) { int score = rand() % 41 + 60; // 60 -100 d.push_back(score); } // 排序 sort(d.begin(), d.end()); // 去出最高分,最低分 d.pop_back(); d.pop_front(); // 计算总分 int sum = accumulate(d.begin(), d.end(), 0); // 计算平均分 int avg = sum / d.size(); // 将平均分同步到用户身上 m[*it].Score[index - 1] = avg; // 将信息存放的临时容器中 mGroup.insert(make_pair(avg, *it)); // 每六个选手选择前三名晋级 if (num % 6 == 0) { /*cout << "小组的比赛成绩如下: " << endl; for (multimap<int, int, greater<int>>::iterator mit = mGroup.begin(); mit != mGroup.end(); mit++) { cout << "编号: " << mit->second << " 姓名: " << m[mit->second].Name << " 得分: " << m[mit->second].Score[index - 1]<< endl; }*/ // 取前三名晋级 cout << "小组的晋级成绩如下: " << endl; int count = 0; for (multimap<int, int, greater<int>>::iterator mit = mGroup.begin(); mit != mGroup.end(), count < 3; count++, mit++) { cout << "晋级编号: " << mit->second << " 姓名: " << m[mit->second].Name << " 得分: " << m[mit->second].Score[index - 1] << endl; // 将前三名存放到 v2 容器中 v2.push_back((*mit).second); } // 清空临时容器 mGroup.clear(); } } } // void showScore(int index, vector<int> &v2, map<int, Speaker> &m) { cout << "第 " << index << " 轮比赛成绩如下: " << endl; for (map<int, Speaker>::iterator it = m.begin(); it != m.end(); it++) { if (it->second.Score[index - 1] <= 0) // 被淘汰的人分数是随机数,可能是0,可能小于0 { continue; } cout << "选手的编号: " << it->first << " 姓名: " << it->second.Name << " 得分: " << it->second.Score[index - 1] << endl; } // 晋级人员编号 cout << "晋级人员编号如下: " << endl; for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++) { cout << "晋级人员编号: " << *it << endl; } } int main() { srand((unsigned int)time(NULL)); vector<int> v; // 存放选手编号的容器 map<int, Speaker> m; // 存放选手以及选手的编号的容器 //1. 创建选手 createSpeaker(v, m); // 2. 抽签 speechDraw(v); // 3. 选手比赛 vector<int> v2; // 第一轮晋级的人员编号的容器 speechContest(1, v, m, v2); // 1 代表第一轮 // 4. 显示得分 showScore(1, v2, m); // 第二轮比赛 speechDraw(v2); // 抽签 vector<int> v3; // 第二轮晋级人员的编号 speechContest(2, v2, m, v3); showScore(2, v3, m); // 第三轮 speechDraw(v3); // 抽签 vector<int> v4; // 第三轮晋级人员的编号 speechContest(3, v3, m, v4); showScore(3, v4, m); /*for (map<int, Spercker>::iterator it = m.begin(); it != m.end(); it++) { cout << "选手编号: " << it->first << " 姓名: " << it->second.Name << " 分数: " << it->second.Score[0] << endl; }*/ return EXIT_SUCCESS; }
Speaker>