每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜。本题就请你实现这个功能。
输入第一行给出一个正整数 N(≤),即考生人数。随后 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
最终AC的代码如下:
#include <iostream> #include <algorithm> #include <map> #include <vector> using namespace std; struct Pair{ double sum; int cnt; Pair(){ sum = 0; cnt = 0; } }; struct School{ string name; int sum, cnt; }; 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 i, n, pre; string s, str; Pair p; School sl; vector<School> ans; map<string, Pair> mp; map<string, Pair>::iterator it; cin>>n; while(n--){ p = Pair(); cin>>str>>p.sum>>s; if(str[0]==‘B‘){ p.sum /= 1.5; }else if(str[0]==‘T‘){ p.sum *= 1.5; } for(i=0; i<s.size(); i++){ if(s[i]>=‘A‘ && s[i]<=‘Z‘){ s[i] += 32; } } it = mp.find(s); if(it != mp.end()){ (it->second).sum += p.sum; (it->second).cnt++; }else{ p.cnt = 1; mp[s] = p; } } for(it=mp.begin(); it!=mp.end(); it++){ sl.name = it->first; sl.sum = (int)(it->second).sum; sl.cnt = (it->second).cnt; ans.push_back(sl); } sort(ans.begin(), ans.end(), cmp); n = 0; pre = -1; printf("%d\n", ans.size()); for(i=0; i<ans.size(); i++){ if(pre!=ans[i].sum){ n = i + 1; pre = ans[i].sum; } printf("%d %s %d %d\n", n, (ans[i].name).c_str(), ans[i].sum, ans[i].cnt); } return 0; }
由题干条件:
输入第一行给出一个正整数 N(≤10?5),即考生人数。
可知,如果直接用vector存储输入的数据的话,后面两个测试用例会超时。而只用map,又不可以得到想要的排序结果(由于map内的元素按键已排序)。可以考虑unorder_map方式,但是考试的时候,不一定所有编译器都支持unorder_map。
因此,比较实用的方式是,用map保存输入的数据,然后,再将已输入数据放入vector中,用sort对vector内的元素排序(毕竟内存一般不会超过题干要求的范围)。
按着这种思路完成代码后,只得了24分,测试用例2一直不能通过。通过分析时间、空间复杂度发现,该测试用例不是拥有大量数据的情况,应该是某个细节没有注意好。后查看别人的博客的分析思路,也没有找到根源。再仔细检查代码,发现下面一行代码(pre是记录上一个加权分数的变量):
pre = 0;
转念一想,测试用例2是不是这种情况呢?
1 A57908 0 Au
那么输出不就成了:
1 0 au 0 1
于是果断将pre的初始值改为了-1,于是顺利地通过了测试用例2(上面输出第一列排名应该是1而非0)。
原文:https://www.cnblogs.com/heyour/p/12243144.html