代码
#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,两个变量同时来表示即可。