学习笔记 STL实例练习

学习笔记 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容器存储分数,晋级序号,
再就是打印了
再选择晋级的再比赛,再晋级,打印了

*/

思路:

  1. 产生选手
  2. 选手的属性赋值,利用string和deque来存储选手的姓名的得分(得分需要去掉最值)
  3. 最值的去除又是利用了deque容器的sort算法,sort(v.begin(),v.end())
  4. 再就是利用map容器来存储<int,Speaker>,这样就很方便了,他既有选手编号又有选手对象
  5. map容器中的key,value又是相互关联的,更符合我们这里的需求
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值