学习笔记 STL实例练习
比赛规则:
某市举行一场演讲比赛( speech_contest ),共有24个人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛。
比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛;
第一轮分为4个小组,每组6个人。比如编号为: 100-123. 整体进行抽签(draw)后顺序演讲。当小组演讲完后,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
第二轮分为2个小组,每组6人。比赛完毕,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
第三轮只剩下1组6个人,本轮为决赛,选出前三名
比赛评分:10个评委打分,去除最低、最高分,求平均分每个选手演讲完由10个评委分别打分。该选手的最终得 分是去掉一个最高分和一个最低分,求得剩下的8个成绩的平均分。选手的名次按得分降序排列。
#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include<map>
#include <numeric>
#include <string>
#include <deque>
#include <functional>
#include<ctime>
/*
1) 产生选手 ( ABCDEFGHIJKLMNOPQRSTUVWX ) 姓名、得分;选手编号
2) 第1轮 选手抽签 选手比赛 查看比赛结果
3) 第2轮 选手抽签 选手比赛 查看比赛结果
4) 第3轮 选手抽签 选手比赛 查看比赛结果
*/
class Speaker
{
public:
//Speaker(int score, string name)
//{
// this->m_score = score;
// this->m_name = name;
//}
public:
int m_score[3];
string m_name;
};
void creatSpeaker(vector<int>& v, map <int,Speaker>& m)
{
string nameSeed = "ABCDEFGHIJKLMNOPQRSTUVWX";
for (int 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);//选手编号
//m.insert(i + 100, sp);
m.insert(make_pair(i + 100, sp));//选手编号和姓名
}
}
void speechDrow(vector<int>&v)//比赛抽签
{
random_shuffle(v.begin(), v.end());
}
//index 第几次比赛 m选手信息, v2晋级选手编号
void speechContest(int index, vector<int>& v1, map<int, Speaker>& m, vector<int>& v2)
{
int num = 0;
multimap<int, int, greater<int> >groupMap;
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() % 40 + 60;
d.push_back(score);//相当于十个评委打分
}
sort(d.begin(), d.end());
d.pop_back();
d.pop_front();//去除最高最低分
int sum = accumulate(d.begin(), d. end(), 0);
//int num2 = accumulate(v1.begin(), v1.end(),0);
int avg = sum / d.size();
m[*it].m_score[index -1] = avg;//m[num]map容器的随机寻址
groupMap.insert(make_pair(avg, *it));//map的insert函数使用
if (num % 6 == 0)
{
int count = 0;
//multimap int 分数 int 晋级序号 Speaker晋级选手信息
for (multimap<int, int, greater<int>>::iterator mit = groupMap.begin(); mit != groupMap.end(), count<3; mit++,count++)
//每六个选手选出前三名晋级
{
v2.push_back(mit->second);
}
groupMap.clear();
}
}
}
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++)
{
cout << "选手编号: " << it->first << "姓名: " << it->second.m_name << "选手得分: "<<it->second.m_score[index-1] << endl;
}
cout << "晋级选手编号" << "及姓名如下:"<<endl;
map<int, Speaker>::iterator it = m.begin();
for (vector<int>::iterator mit = v.begin(); mit != v.end(); mit++)
{
cout << *mit << " " << m[*mit].m_name<<endl;
}
}
int main(void)
{
srand((unsigned int)time(NULL));
vector<int>v;//选手编号
map<int, Speaker>m;
creatSpeaker( v, m);
vector<int>v2;
cout << "第一轮比赛:" << endl;
speechDrow(v);
speechContest(1, v, m, v2);
showScore(1, v2, m);
cout << "第二轮比赛:" << endl;
vector<int>v3;
speechContest(2, v2, m, v3);
showScore(2, v3, m);
cout << "第三轮比赛:" << endl;
vector<int>v4;
speechContest(3, v3, m, v4);
showScore(2, v4, m);
//for (map<int, Speaker>::iterator it = m.begin(); it != m.end(); it++)
//{
// cout << "编号: " << it->first << "姓名为: " << it->second.m_name << endl;
//}
/*for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
}*/
return 0;
}
/*
整个思路是什么样子的呢:
用map容器存储比赛选手的编号和选手类,选手类里面有选手的每一轮的得分和选手姓名
在生成选手姓名的时候灵活运用string的length,和+=;还有就是运用了随机数给选手打分,并且用临时的deque容器把
十个评委分数存储方便去除最高分和最低分,deque.pop_back(),deque.pop_front();
之后计算平均分给map容器里面的Speaker类里面的m_score
再就是利用另外临时multimap容器存储分数,晋级序号,
再就是打印了
再选择晋级的再比赛,再晋级,打印了
*/
思路:
- 产生选手
- 选手的属性赋值,利用string和deque来存储选手的姓名的得分(得分需要去掉最值)
- 最值的去除又是利用了deque容器的sort算法,sort(v.begin(),v.end())
- 再就是利用map容器来存储<int,Speaker>,这样就很方便了,他既有选手编号又有选手对象
- map容器中的key,value又是相互关联的,更符合我们这里的需求