[湖南大学程序设计实训训练作业一]6.世界杯来了(字符串处理substr+map+vector_sort*2,最后还有一次字典排序)

【问题描述】

2018年俄罗斯世界杯结束了,法国获得冠军,全世界球迷度过了一个非常愉快的夏天。作为中国球迷,不能总是看别人踢球,这不福利来了,根据FIFA(国际足联)及全体成员协会的一致决定,2118年世界杯将在中国举办,作为东道主,中国队将无需参加预选赛而直接参加决赛阶段的比赛。

比赛规则如下:

  • 总共n(n为偶数)个球队参加比赛

  • 按照分组赛积分排名,前n/2的球队进入淘汰赛

  • 积分排名的规则如下:球队获胜得3分,平局得1分,失利得0分,按照积分递减、净胜球递减以及进球数递减方式排名

编写一个程序,根据给出的参赛队伍名单和所有比赛的结果,找出成功进入淘汰赛阶段的球队名单。

【输入形式】

第一行输入包含唯一整数n(1<=n<=50),参加世界杯决赛的球队数量。接下来的n行是各球队的名字,为长度不超过30个字符的英文字符。接下来的n*(n-1)/2行,每行格式name1-name2 num1:num2(0<=num1, num2<=100),表示对阵球队及比分.

【输出形式】

输入n/2行,表示进入淘汰赛阶段的球队,按照字典序进行排列,每个球队名字占一行。

【样例输入】

4
A
B
C
D
A-B 1:1
A-C 2:2
A-D 1:0
B-C 1:0
B-D 0:3
C-D 0:3

【样例输出】

A
D

题解

思路

  • 1.我们要处理字符串。拿出队伍名字和得分,得分还要做一个字符串数字转换,直接用到substr和sstream。
  • 2.map存储队伍得分。如果直接用vector,每次还要遍历去找,复杂度太高了
  • 3.map转存到vector,自定义cmp排序规则用algorithm里面自带的排序得到淘汰赛的队伍
  • 4.将淘汰赛的队伍的名字进行排序,变成字典序,然后输出
  • 注意:getline()之前需要cin.ignore()一次,把上一次输入的换行给忽视掉

代码

#include<iostream>
#include<map>
#include<vector>
#include<string> 
#include<algorithm>
#include<sstream> 
using namespace std;
struct score{
	int score;
	int win_goal;
	int goal; 
};
struct team{
	string name;
	score res;
	//int score;
	//int win_goal;
};
bool cmp(team a,team b){
	if(a.res.score!=b.res.score){
		return a.res.score>b.res.score;
	}else if(a.res.win_goal!=b.res.win_goal){
		return a.res.win_goal>b.res.win_goal;
	}else{
		return a.res.goal>b.res.goal;
	}
}
int get_score(string s){
	int num;
	stringstream ss(s);
	ss>>num;
	return num;
}
int main(){
	map<string,score> m;
	vector<team> res; 
	vector<string> f_res;
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		string temp;
		cin>>temp;
		m[temp].score=0;
		m[temp].win_goal=0;
		m[temp].goal=0;
	}
	int cnt=n*(n-1)/2;
	cin.ignore();
	while(cnt--){
		string s;
		getline(cin,s);
		string teamA,teamB;
		int scoreA,scoreB;
		int flag1,flag2;
		for(int i=0;i<s.length();i++){
			/******************字符信息提取************************/
			if(s[i]=='-'){
				flag1=i;
				teamA=s.substr(0,i);
				//cout<<teamA<<endl;
			}else if(s[i]==' '){
				flag2=i;
				teamB=s.substr(flag1+1,i-flag1-1);
				//cout<<teamB<<endl;
			}else if(s[i]==':'){
				string temp_scoreA,temp_scoreB;
				temp_scoreA=s.substr(flag2+1,i-flag2-1);
				temp_scoreB=s.substr(i+1,s.length()-1-i);
				scoreA=get_score(temp_scoreA);
				scoreB=get_score(temp_scoreB);
				//cout<<scoreA<<" "<<scoreB<<endl;
				//cout<<temp_scoreA<<" "<<temp_scoreB<<endl;
			}
		}
		/******************比较积分************************/
		if(scoreA>scoreB){
			m[teamA].score+=3;
		}else if(scoreA<scoreB){
			m[teamB].score+=3;
		}else{
			m[teamA].score+=1;
			m[teamB].score+=1;
		}
		m[teamA].win_goal+=scoreA-scoreB;
		m[teamB].win_goal+=scoreB-scoreA;
		m[teamA].goal+=scoreA;
		m[teamB].goal+=scoreB;
		//cout<<teamA<<" "<<m[teamA].score<<" "<<m[teamA].win_goal<<endl;
		//cout<<teamB<<" "<<m[teamB].score<<" "<<m[teamB].win_goal<<endl;
	}
	/******************map转vector进行sort排序************************/
	for(map<string,score>::iterator it=m.begin();it!=m.end();it++){
		team temp;
		temp.name=it->first;
		temp.res=it->second;
		res.push_back(temp);
	}
	sort(res.begin(),res.end(),cmp);
	/******************拿出积分和净胜球的排序,再次进行字典序************************/
	for(int i=0;i<n/2;i++){
		f_res.push_back(res[i].name);	
	}
	sort(f_res.begin(),f_res.end());
	for(int i=0;i<f_res.size();i++){
		cout<<f_res[i]<<endl;
	}
	return 0;
} 

评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值