每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜。本题就请你实现这个功能。
输入格式:
输入第一行给出一个正整数N(<=105),即考生人数。随后N行,每行按下列格式给出一个考生的信息:
准考证号 得分 学校
其中“准考证号”是由6个字符组成的字符串,其首字母表示考试的级别:“B”代表乙级,“A”代表甲级,“T”代表顶级;“得分”是 [0,100] 区间内的整数;“学校”是由不超过6个英文字母组成的单位码(大小写无关)。注意:题目保证每个考生的准考证号是不同的。
输出格式:
首先在一行中输出单位个数。随后按以下格式非降序输出单位的排行榜:
排名 学校 加权总分 考生人数
其中“排名”是该单位的排名(从1开始);“学校”是全部按小写字母输出的单位码;“加权总分”定义为“乙级总分/1.5 + 甲级总分 + 顶级总分*1.5”的整数部分;“考生人数”是该属于单位的考生的总人数。
学校首先按加权总分排行。如有并列,则应对应相同的排名,并按考生人数升序输出。如果仍然并列,则按单位码的字典序输出。
输入样例:10 A57908 85 Au B57908 54 LanX A37487 60 au T28374 67 CMU T32486 24 hypu A66734 92 cmu B76378 71 AU A47780 45 lanx A72809 100 pku A03274 45 hypu输出样例:
5 1 cmu 192 2 1 au 192 3 3 pku 100 1 4 hypu 81 2 4 lanx 81 2
感冒了刷题脑子都短路,题目说的是把总分除以1.5或者乘以1.5,而不是看到一个就要计算,难怪最后一个点总是不对。。。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <algorithm> using namespace std; struct pat { char num[7],school[7]; int af,bf,tf,snum,f; }s[100001]; int n,c,f; char num[7],school[7]; map<string,int> q; bool cmp(pat a,pat b) { if(a.f == b.f) { if(a.snum == b.snum) { return strcmp(a.school,b.school) < 0; } return a.snum < b.snum; } return a.f > b.f; } void low(char *t) { for(int i = 0;t[i];i ++) t[i] = tolower(t[i]); } int main() { scanf("%d",&n); for(int i = 0;i < n;i ++) { scanf("%s%d%s",num,&f,school); low(school); if(!q[school])q[school] = ++ c,strcpy(s[c].school,school); s[q[school]].snum ++; if(num[0] == 'A')s[q[school]].af += f; else if(num[0] == 'B')s[q[school]].bf += f; else s[q[school]].tf += f; } for(int i = 1;i <= c;i ++) { s[i].f = s[i].af + s[i].bf / 1.5 + s[i].tf * 1.5; } sort(s + 1,s + c + 1,cmp); int d = 1; printf("%d ",c); for(int i = 1;i <= c;i ++) { if(s[i].f != s[i - 1].f)d = i; printf("%d %s %d %d ",d,s[i].school,s[i].f,s[i].snum); } }