c++从入门到精通——STL综合案例(学校演讲比赛)
STL综合案例(学校演讲比赛)某市举行一场演讲比赛( speech_contest ),共有24个人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛。比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛;第一轮分为4个小组,每组6个人。比如编号为: 100-123.整体进行抽签(draw)后顺序演讲。当小组演讲完后,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。第二轮分为2个小组,每
STL综合案例(学校演讲比赛)
某市举行一场演讲比赛( speech_contest ),共有24个人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛。
比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛;
第一轮分为4个小组,每组6个人。比如编号为: 100-123. 整体进行抽签(draw)后顺序演讲。
当小组演讲完后,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
第二轮分为2个小组,每组6人。比赛完毕,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
第三轮只剩下1组6个人,本轮为决赛,选出前三名。
比赛评分:10个评委打分,去除最低、最高分,求平均分每个选手演讲完由10个评委分别打分。
该选手的最终得分是去掉一个最高分和一个最低分,求得剩下的8个成绩的平均分。选手的名次按得分降序排列。
用STL编程,求解这个问题
1) 请打印出所有选手的名字与参赛号,并以参赛号的升序排列。
2) 打印每一轮比赛后,小组比赛成绩和小组晋级名单
代码与思路
首先生成选手,每一位选手都有名字,参赛号,比赛成绩三个属性。
名字
,可以用A到X表示。
得分
,可以用整型数组存储,第1,2,3轮比赛成绩(10个评委打分,去除最低、最高分,求平均分得来)。用双端队列deque
存储10个分数,排序sort,去尾pop_back,去头pop_front,累加accumulate,最后总分除以队列长度得平均分,也就是当前选手本轮比赛的得分。
参赛号
,可以用3位整数表示,例如100~123,为了方便随机,把参赛号独立出来,用vector<int>
存储,用map关联参赛号
与选手
,用random_shuffle函数对vector<int>
存储的参赛号洗牌。
string m_Name; //姓名
int m_Score[3]; //得分数组,第1,2,3轮得分
int num; //参赛号,用100到123表示。
需不需要组号
呢,其实,可以不需要。因为,24个人比赛,淘汰一半,剩12个人,12个人比赛,淘汰一半,剩6个人。数字24,12,6都可以整除6,而6又可以整除3,取前三名。
梳理流程
整体流程
创建选手---------createSpeaker
抽签------------speechDraw
比赛1-----------speechContest----输入vector1,得到vector2
显示比赛结果-----showScore
比赛2-----------speechContest----输入vector2,得到vector3
显示比赛结果-----showScore
比赛3-----------speechContest----输入vector3,得到vector4
显示比赛结果-----showScore
比赛流程
遍历所以比赛选手
计算选手得分流程
累计6个选手
6取3,添加到结果集
代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <deque>
#include <numeric>
#include <functional>
#include <ctime>
/*
1) 产生选手 ( ABCDEFGHIJKLMNOPQRSTUVWX ) 姓名、得分;选手编号
2) 第1轮 选手抽签 选手比赛 查看比赛结果
3) 第2轮 选手抽签 选手比赛 查看比赛结果
4) 第3轮 选手抽签 选手比赛 查看比赛结果
*/
class Speaker
{
public:
string m_Name; //姓名
int m_Score[3]; //得分数组
};
void createSpeaker(vector<int>& v, map<int, Speaker>& m)
{
string nameSeed = "ABCDEFGHIJKLMNOPQRSTUVWX";
for (size_t i = 0; i < nameSeed.size(); i++)
{
string name = "选手";
name += nameSeed[i];
Speaker sp;
sp.m_Name = name;
for (int j = 0; j < 3; j++)
{
sp.m_Score[j] = 0;
}
v.push_back(i + 100); //编号 100 ~ 123
m.insert(make_pair(i + 100, sp));
}
}
//抽签
void speechDraw(vector<int>v)
{
//洗牌
random_shuffle(v.begin(), v.end());
}
// 1 第几轮 2 v1比赛选手编号 3 m是选手编号和具体选手 4 v2 晋级选手编号容器
void speechContest(int index, vector<int>& v1, map<int, Speaker>& m, vector<int>& v2)
{
multimap<int, int, greater<int>> groupMap; // key 分数 value 编号
int num = 0;
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
num++;
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容器中
m[*it].m_Score[index - 1] = avg;
//每6个人 取前三名 晋级
//临时容器 保存6个人
//临时容器 存入数据
groupMap.insert(make_pair(avg, *it));
if (num % 6 == 0)
{
/* cout << "小组比赛成绩如下:" << endl;
for (multimap<int, int, greater<int>>::iterator mit
= groupMap.begin(); mit != groupMap.end();mit++)
{
cout << "编号: " << mit->second <<
" 姓名:" << m[mit->second].m_Name <<
"得分:" << m[mit->second].m_Score[index - 1] << endl;
}
*/
//取前三名
int count = 0;
for (multimap<int, int, greater<int>>::iterator mit
= groupMap.begin(); mit != groupMap.end(), count < 3; mit++, count++)
{
//晋级容器 获取获取数据
v2.push_back(mit->second);
}
groupMap.clear(); //清空临时容器
}
}
}
//是否晋级
string isPromotion(int num, vector<int>& v) {
vector<int>::iterator it = find(v.begin(), v.end(), num);
if (it != v.end()) {
return " ★晋级";
}else {
return "";
}
}
void showScore(int index, vector<int>& v, map<int, Speaker>& m)
{
cout << "第" << index << "轮 比赛成绩如下:" << endl;
for (map<int, Speaker>::iterator it = m.begin(); it != m.end(); it++)
{
if (0 == it->second.m_Score[index - 1])continue;
string ss = isPromotion(it->first,v);
cout << "选手编号: " << it->first << " 姓名: " << it->second.m_Name << " 分数: " << it->second.m_Score[index - 1] << ss <<endl;
}
cout << "晋级选手编号" << endl;
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
}
}
测试
int main() {
//随机数种子
srand((unsigned int)time(NULL));
vector<int> v1; //选手编号
map<int, Speaker>m; //存放选手编号 和对应的具体的选手
//创建选手
createSpeaker(v1, m);
//抽签
speechDraw(v1);
vector<int> v2; // 进入下一轮比赛的人员编号
//比赛
speechContest(1, v1, m, v2);
//显示比赛结果
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, Speaker>::iterator it = m.begin(); it != m.end();it++)
//{
// cout << "编号:" << it->first << " 姓名" << it->second.m_Name << endl;
//}
system("pause");
return EXIT_SUCCESS;
}
输出
- - - 第1轮 比赛成绩如下 - - -
选手编号: 100 姓名: 选手A 分数: 80
选手编号: 101 姓名: 选手B 分数: 75
选手编号: 102 姓名: 选手C 分数: 82
选手编号: 103 姓名: 选手D 分数: 80
选手编号: 104 姓名: 选手E 分数: 77
选手编号: 105 姓名: 选手F 分数: 77
选手编号: 106 姓名: 选手G 分数: 76
选手编号: 107 姓名: 选手H 分数: 77
选手编号: 108 姓名: 选手I 分数: 76
选手编号: 109 姓名: 选手J 分数: 79
选手编号: 110 姓名: 选手K 分数: 80
选手编号: 111 姓名: 选手L 分数: 84
选手编号: 112 姓名: 选手M 分数: 77
选手编号: 113 姓名: 选手N 分数: 80
选手编号: 114 姓名: 选手O 分数: 83
选手编号: 115 姓名: 选手P 分数: 84
选手编号: 116 姓名: 选手Q 分数: 78
选手编号: 117 姓名: 选手R 分数: 78
选手编号: 118 姓名: 选手S 分数: 75
选手编号: 119 姓名: 选手T 分数: 84
选手编号: 120 姓名: 选手U 分数: 79
选手编号: 121 姓名: 选手V 分数: 76
选手编号: 122 姓名: 选手W 分数: 86
选手编号: 123 姓名: 选手X 分数: 75
晋级选手编号
102
100
103
111
110
109
115
114
113
122
119
120
- - - 第2轮 比赛成绩如下 - - -
选手编号: 100 姓名: 选手A 分数: 78
选手编号: 102 姓名: 选手C 分数: 83
选手编号: 103 姓名: 选手D 分数: 85
选手编号: 109 姓名: 选手J 分数: 85
选手编号: 110 姓名: 选手K 分数: 84
选手编号: 111 姓名: 选手L 分数: 80
选手编号: 113 姓名: 选手N 分数: 83
选手编号: 114 姓名: 选手O 分数: 83
选手编号: 115 姓名: 选手P 分数: 86
选手编号: 119 姓名: 选手T 分数: 82
选手编号: 120 姓名: 选手U 分数: 84
选手编号: 122 姓名: 选手W 分数: 73
晋级选手编号
103
109
110
115
120
114
- - - 第3轮 比赛成绩如下 - - -
选手编号: 103 姓名: 选手D 分数: 85
选手编号: 109 姓名: 选手J 分数: 81
选手编号: 110 姓名: 选手K 分数: 82
选手编号: 114 姓名: 选手O 分数: 83
选手编号: 115 姓名: 选手P 分数: 83
选手编号: 120 姓名: 选手U 分数: 73
晋级选手编号
103
115
114
stl之random_shuffle函数例子
随机重新排列范围(first,last)中的元素
// random_shuffle example
#include <iostream> // std::cout
#include <algorithm> // std::random_shuffle
#include <vector> // std::vector
#include <ctime> // std::time
#include <cstdlib> // std::rand, std::srand
// random generator function:
int myrandom (int i) { return std::rand()%i;}
int main () {
//随机数种子
std::srand ( unsigned ( std::time(0) ) );
std::vector<int> myvector;
// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
// using built-in random generator:
std::random_shuffle ( myvector.begin(), myvector.end() );
// using myrandom:
std::random_shuffle ( myvector.begin(), myvector.end(), myrandom);
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
Possible output:
myvector contains: 3 4 1 6 8 9 2 7 5
std之multimap
Multiple-key map
template < class Key,
// multimap::key_type class T,
// multimap::mapped_type class Compare = less<Key>,
// multimap::key_compare class Alloc = allocator<pair<const Key,T> >
// multimap::allocator_type> class multimap;
multimap是关联式容器,它按特定的次序(按照key来比较)存储由键key和值value组合而成的元素,多个键值对之间的key可以重复
更多推荐
所有评论(0)