PAT-乙-1085 1085 PAT单位排行 (25 分)
PAT-乙-1085 1085 PAT单位排行 (25 分)

代码

#include <iostream>
#include <map>
#include <algorithm>

using namespace std;

struct company {
	int rank;
	string name;
	int sum;
	double sumtmp;
	int count;
};

int compare(company c1, company c2) {
	return c1.sum!=c2.sum?c1.sum>c2.sum:(c1.count!=c2.count?c1.count<c2.count:c1.name<c2.name);
}

double weightScore(string id, int score) {
	double ans = score;
	if(id.at(0)=='T') {
		ans = score * 1.5;
	} else if(id.at(0)=='B') {
		ans = score / 1.5;
	}
	return ans;
}

string lower(string s) {
	for(int i=0; i<s.length(); i++) {
		if(s[i]>='A' && s[i]<='Z') {
			s[i] = (char)(s[i]+32);
		}
	}
	return s;
}

int main() {
	
	int n;
	cin>>n;

	map<string, int> m;
	int nowpos = 1;
	company com[n+1];

	for(int i=0; i<n; i++) {
		string sid, sschool;
		int score;
		cin>>sid>>score>>sschool;
		sschool = lower(sschool);
		double score1 = weightScore(sid, score);
		if(!m[sschool]) {
			m[sschool] = nowpos;
			com[nowpos].name = sschool;
			com[nowpos].sumtmp = 0;
			com[nowpos].count = 0;
			nowpos++;
		}
		int tmp = m[sschool];
		com[tmp].sumtmp += score1;
		com[tmp].count += 1;
	}

	for(int i=1; i<nowpos; i++) {
		com[i].sum = (int)com[i].sumtmp;
	}

	sort(com+1, com+nowpos, compare);
	
	int nowRank = 1;
	int same = 1;
	com[1].rank = 1;
	for(int i=2; i<nowpos; i++){
		if(com[i].sum==com[i-1].sum){
			com[i].rank = com[i-1].rank;
			same++;
		}
		else{
			com[i].rank = com[i-1].rank + same;
			nowRank = com[i].rank;
			same = 1;
		}
	}

	cout<<nowpos-1<<endl;
	for(int i=1; i<nowpos; i++) {
		cout<<com[i].rank<<" "<<com[i].name<<" "<<com[i].sum<<" "<<com[i].count<<endl;
	}

}

注解

1、由于map<string, int>,int的值默认为0,此题要想不超时,必须建立<key, value>的映射关系。那么int的值应该从1开始,为了方便,com数组也从1开始,因此com的初始化长度必须是n+1,而不是n(否则会出现段错误,因为是从数组下标1开始存的,要想存n个,截止位置应该是n,而数组下标从0开始,所以定义的长度必须为n+1)。本题map映射关系是不超时的关键。
2、结构体排序就不多说了,要会写compare函数。此外,结构体的成员变量有哪些,应该仔细考虑。主要是依据要输出的元素考虑,另外由于总得分取整数,而乙级得分/1.5的时候有可能出现小数,因此应该有个double类型的sum,以及int类型的sum。
3、注意单位名称的大小写转换。因为单位名称是不区分大小写的,输出统一为小写。
4、当总分一致时,排名相同。这里要注意排名相同如何处理的。用一个nowRank和一个same,两个变量同时来表示即可。

结果

PAT-乙-1085 1085 PAT单位排行 (25 分)

相关文章: