PAT B1085 PAT单位排行(C++)

PAT甲级目录 | PAT乙级目录

题目描述

B1085 PAT单位排行

解题思路

利用 map 来获得学校编号,并根据对应学生成绩的标签,将成绩累加到学校分数中。再排序,输出结果。

易错点

  • 输入的是否应先将学校名称统一转换为小写
  • 排序前应先将学校总分转换为整型
  • 排序按照总分降序、人数升序、学校名称升序

也许陌生的知识点

  • ctype 头文件包含一系列处理单个字符的函数:
    • islower()
      • 判断字符是否为小写字母
    • isupper()
      • 判断字符是否为大写字母
    • y = tolower(x)
      • 将大写字母转换为小写字母
    • y = toupper(x)
      • 将小写字母转换为大写字母
  • sort(S, S + n, cmp);
    • 排序函数,实现 [first, last) 范围内的排序,可以自定义排序策略 cmp 函数
    • 不带 cmp 参数的 sort 函数实现从小到大排序
    • 所需头文件: algorithm

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <string>
#include <map>
#include <cctype>
#include <algorithm>
#include <iostream>
using namespace std;
struct School{
double score = 0;
int cnt = 0, sum;
string name;
}S[100010];
bool cmp(School a, School b){
if(a.sum != b.sum) return a.sum > b.sum;
else if(a.cnt != b.cnt) return a.cnt < b.cnt;
else return a.name < b.name;
}
int main(){
int n, t, score, cnt = 0;
char tag;
string sch;
map<string, int> m;
scanf("%d", &n);
for(int i = 0; i < n; i++){
cin >> tag >> t >> score >> sch;
for(int j = 0; j < sch.length(); j++){
if(isupper(sch[j])) sch[j] = tolower(sch[j]);
}
if(m.find(sch) == m.end()){
S[cnt].name = sch;
m[sch] = cnt++;
}
if(tag == 'B') S[m[sch]].score += 1.0 * score / 1.5;
else if(tag == 'A') S[m[sch]].score += 1.0 * score;
else S[m[sch]].score += 1.5 * score;
S[m[sch]].cnt++;
}
for(int i = 0; i < cnt; i++) S[i].sum = (int)S[i].score;
sort(S, S + cnt, cmp);
printf("%d\n", cnt);
for(int i = 0, r = 0; i < cnt; i++){
if(i > 0 && S[i].sum != S[i-1].sum) r = i;
cout << r + 1 << " " + S[i].name;
printf(" %d %d\n", S[i].sum, S[i].cnt);
}
return 0;
}