这一题是根据各学校学生的PAT的A、B、T三等级的成绩,对学校的总成绩进行排序,总成绩=A+B/1.5+T*1.5。每个学校的A、B、T成绩可能多个,要把所有的分别加起来,同时把总的个数ns要统计出来。首先根据总成绩进行逆序排序,在总成绩相等的情况下再根据个数ns进行顺序排序,在前两个相等的情况下根据学校名称顺序排序。
建立一个结构体数组,然后用map将学校和数组下标关联,用map对象的count()判断是否存在这个元素,有则在原来基础上增加成绩,没有则再给一个新的元素,在map中将学校和下标关联,处理完后排序。这一题刚开始做好,最后两个测试点时间超限,原来以为是将学校名称转化为小写花费太多时间了,但不知道怎么改。看了一下别人的,才知道可能是排序超时,于是改用了sort(现在才发现如果是排序超时,让自己改,自己也只能用sort,会写的排序算法最差的情况都是
O
(
n
2
)
O(n^2)
O(n2))。
这里也算知道map的用法,除了用find以外,还可以用count判断值是否存在。
#include <bits/stdc++.h>
using namespace std;
const int LENGTH= 201;
struct School {
string sName;
int tws;
int scoreB;
int scoreA;
int scoreT;
int ns;
School(){
tws=0;
scoreB=0;
scoreA=0;
scoreT=0;
ns=1;
}
};
bool cmp(School a,School b){
if(a.tws != b.tws){
return a.tws > b.tws;
}
else{
if(a.ns!=b.ns){
return a.ns<b.ns;
}
return a.sName<b.sName;
}
}
int main()
{
int n;
cin>>n;
School school[n];
int sLength = 0;
string testID,schName;
int num;
map<string,int> schIndexMap;
int index;
for(int i=0; i<n; i++) {
cin>>testID>>num>>schName;
for(int j=0;j<schName.size();j++){
if(schName[j]>='A'&&schName[j]<='Z'){
schName[j] = schName[j]-'A'+ 'a';
}
}
if(schIndexMap.count(schName)==0) {
schIndexMap.insert(pair<string, int>(schName, sLength));
school[sLength].sName = schName;
switch(testID[0]) {
case 'A':
school[sLength].scoreA = num;
break;
case 'B':
school[sLength].scoreB = num;
break;
default:
school[sLength].scoreT = num;
break;
}
sLength++;
} else {
index =schIndexMap[schName];
switch(testID[0]) {
case 'A':
school[index].scoreA += num;
break;
case 'B':
school[index].scoreB += num;
break;
default:
school[index].scoreT += num;
break;
}
school[index].ns++;
}
}
for(int i=0; i<sLength; i++) {
school[i].tws = school[i].scoreA + school[i].scoreB/1.5 +school[i].scoreT*1.5;
}
sort(school,school+sLength,cmp);
int schRank =1;
cout<< sLength<<endl;
for(int i=0; i<sLength; i++) {
if(i>0&&school[i].tws<school[i-1].tws) {
schRank=i+1;
}
cout<<schRank<<" "<<school[i].sName<<" "<<school[i].tws<<" "<< school[i].ns << endl;
}
return 0;
}