C++提高案例之-演讲比赛流程管理系统

1. 需求

1.一共12个参赛者,比赛共两轮
2.选手编号对应为10001-10012。
3.分组比赛,每组6人。
4.第一轮分两组,按照选手编号进行抽签后顺序演讲。
5.十个评委分别打分,去除最高最低分求平均分作为选手成绩。
6.第一轮每组淘汰最差的三人,前三名晋级进入第二轮。
7.第二轮前三名胜出。
8.每轮结束后显示晋级选手信息。

思路
1.使用map<int, Person>保存选手编号,姓名,成绩等信息。
2.分组手动分,两个map分别存放。
3.抽签就是打乱顺序,如果用map的话不能直接用shuffle,transorm等标准算法,自己写。
4.每轮结束按照分数进行排序并显示信息,其中第一轮结束后需要将两个map的前三名放进新的容器进入第二轮。

没跟老师自己敲了个,处理了一下同分晋级的情况:

class Person {
public:
	Person(char name, int score) {
		this->name = name;
		this->score = score;
	}
	char name;
	int score;
};

void save_csv(map<int, Person>& v) {
	ofstream ofs;
	//write & save every games
	ofs.open("speech.csv", ios::out | ios::app);

	for (map<int, Person>::iterator it = v.begin(); it != v.end(); it++) {
		ofs << "NO:" << (*it).first << " "
			<< "Name:" << (*it).second.name << " "
			<< "Score:" << (*it).second.score << endl;
	}
	ofs << endl;
	ofs.close();
	cout << "save success!" << endl;
}

void create1(map<int, Person>& v) {
	string nameseed = "ABCDEF";
	deque<int>s;
	//构造对象
	for (int i = 0; i < 6; i++) {
		int score = 0;
		//评分
		for (int j = 0; j < 10; j++) {
			s.push_back(rand() % 60 + 40);
		}
		sort(s.begin(), s.end());
		s.pop_front();
		s.pop_back();
		//取平均分
		for (deque<int>::iterator it = s.begin(); it != s.end(); it++) {
			score += (*it);
		}
		score /= s.size();
		Person p(nameseed[i], score);
		v.insert(pair<int, Person>(10001 + i, p));
	}
}

void create2(map<int, Person>& v) {
	string nameseed = "GHIJKL";
	deque<int>s;

	for (int i = 0; i < 6; i++) {
		int score = 0;

		for (int j = 0; j < 10; j++) {
			s.push_back(rand() % 60 + 40);
		}
		sort(s.begin(), s.end());
		s.pop_front();
		s.pop_back();

		for (deque<int>::iterator it = s.begin(); it != s.end(); it++) {
			score += (*it);
		}
		score /= s.size();
		Person p(nameseed[i], score);
		v.insert(pair<int, Person>(10007 + i, p));
	}
}

void show(map<int, Person>& v) {
	for (map<int, Person>::iterator it = v.begin(); it != v.end(); it++) {
		cout << (*it).first << " " << (*it).second.name << " " << (*it).second.score << endl;
	}
	cout << endl;
}

void shuffle_speak(map<int, Person>& v, map<int, Person>& k) {
	vector<int> v1,v2;
	for (int i = 10001; i < 10007; i++) { 
		v1.push_back(i); 
	}
	for (int i = 10007; i < 10013; i++) {
		v2.push_back(i);
	}
	random_shuffle(v1.begin(), v1.end());
	random_shuffle(v2.begin(), v2.end());

	for (vector<int>::iterator pos = v1.begin(); pos != v1.end(); pos++) {
		for (map<int, Person>::iterator it = v.begin(); it != v.end(); it++) {
			if ((*it).first == (*pos)) {
				cout << (*it).first << (*it).second.name << " is speaking" << endl;
			}
		}
	}
	cout << endl;
	for (vector<int>::iterator pos = v2.begin(); pos != v2.end(); pos++) {
		for (map<int, Person>::iterator it = k.begin(); it != k.end(); it++) {
			if ((*it).first == (*pos)) {
				cout << (*it).first << (*it).second.name << " is speaking" << endl;
			}
		}
	}
}

int give_score() {
	deque<int>s;
	int score = 0;
	//评分
	for (int j = 0; j < 10; j++) {
		s.push_back(rand() % 60 + 40);
	}
	sort(s.begin(), s.end());
	s.pop_front();
	s.pop_back();
	//取平均分
	for (deque<int>::iterator it = s.begin(); it != s.end(); it++) {
		score += (*it);
	}
	score /= s.size();
	return score;
}

void addtimegame(map<int, Person>& v) {
	bool coo = true;
	while(coo) {
		int nums = 0;
		vector<int>index;
		for (map<int, Person>::iterator it = v.begin(); it != v.end(); it++) {
			int num = 0; //统计对于当前选手成绩的同分个数
			for (map<int, Person>::iterator pos = v.begin(); pos != v.end(); pos++) {
				if ((*it).second.score == (*pos).second.score) {
					num += 1;
				}
			}
			//num<=1说明该选手只和自己同分
			if (num <= 1) {
				nums += 1; //统计没撞分的人数
			}
			else {
				index.push_back((*it).first);
			}
		}
		//组内所有人都没撞分,退出循环
		if (nums == 6) {
			coo = false;
		}
		//否则,重新赋分
		else {
			for (vector<int>::iterator pos = index.begin(); pos != index.end(); pos++) {
				for (map<int, Person>::iterator it = v.begin(); it != v.end(); it++) {
					if ((*it).first == (*pos)) {
						(*it).second.score = give_score();
					}
				}
			}
		}
	}
}

void del(map<int, Person>& v, map<int, Person>& k) {
	vector<int>v1, v2;
	//这里需要处理组内同分的情况,只有前三晋级的情况下同分怎么算
	//处理对策,对同分的搞个加时赛,重新赋分,直到组内没有重分为止。
	addtimegame(v);
	addtimegame(k);
	cout << "after addtimegame:" << endl;
	for (map<int, Person>::iterator it = v.begin(); it != v.end(); it++) {
		int flag = 0;
		for (map<int, Person>::iterator pos = v.begin(); pos != v.end(); pos++) {
			if ((*it).second.score < (*pos).second.score) {
				flag += 1;
			}
		}
		if (flag >= 3) {
			v1.push_back((*it).first);
		}
	}
	for (map<int, Person>::iterator it = k.begin(); it != k.end(); it++) {
		int flag = 0;
		for (map<int, Person>::iterator pos = k.begin(); pos != k.end(); pos++) {
			if ((*it).second.score < (*pos).second.score) {
				flag += 1;
			}
		}
		if (flag >= 3) {
			v2.push_back((*it).first);
		}
	}
	for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
		v.erase((*it));
	}
	for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++) {
		k.erase((*it));
	}
}

void My_transform(map<int, Person>& v1, map<int, Person>& v2, map<int, Person>& k) {
	for (map<int, Person>::iterator it = v1.begin(); it != v1.end(); it++) {
		k.insert((*it));
	}
	for (map<int, Person>::iterator it = v2.begin(); it != v2.end(); it++) {
		k.insert((*it));
	}
}

void del_final(map<int, Person>& v) {
	vector<int>v1;
	addtimegame(v);
	cout << "after addtimegame:" << endl;
	for (map<int, Person>::iterator it = v.begin(); it != v.end(); it++) {
		int flag = 0;
		for (map<int, Person>::iterator pos = v.begin(); pos != v.end(); pos++) {
			if ((*it).second.score < (*pos).second.score) {
				flag += 1;
			}
		}
		if (flag >= 3) {
			v1.push_back((*it).first);
		}
	}
	for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
		v.erase((*it));
	}
}

void score_final(map<int, Person>& v) {
	for (map<int, Person>::iterator it = v.begin(); it != v.end(); it++) {
		(*it).second.score = give_score();
	}
}

int main() {
	srand(time(NULL));

	map<int, Person>m1, m2, ans;
	create1(m1);
	create2(m2);
	//抽签-speak
	cout << "开始第一轮演讲:" << endl;
	shuffle_speak(m1, m2);  //注意,这个函数实际上没有发生交换,因为map是有序的
	//第一轮结束,淘汰合并
	cout << "第一轮结束,结算:" << endl;
	del(m1, m2);
	cout << "第一轮第一组晋级名单:" << endl;
	show(m1);
	cout << "第一轮第二组晋级名单:" << endl;
	show(m2);
	//第二轮
	cout << "决赛:" << endl;
	My_transform(m1, m2, ans);
	//第二轮赋分
	score_final(ans);
	del_final(ans);
	cout << "前三甲名单:" << endl;
	show(ans);
	return 0;
}
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值