/**
* 1.解题思路:两个map,一个cnt用来存储某学校名称对应的参赛人数
* 另一个sum计算某学校名称对应的总加权成绩。
* 每次学校名称string school都要转化为全小写
* 将map中所有学校都保存在vector ans中
* 类型为node,node中包括学校姓名、加权总分、参赛人数。对ans数组排序
* 根据题目要求写好cmp函数,最后按要求输出。对于排名的处理:
* 设立pres表示前一个学校的加权总分,如果pres和当前学校的加权总分不同
* 说明rank等于数组下标+1,否则rank不变
*
* 2.注意:总加权分数取整数部分是要对最后的总和取整数部分,不能每次都直接用int存储,不然会有一个3分测试点不通过
* 更新后的pat系统会导致之前使用map的代码最后一个测试点超时,更改为unordered_map即可AC
*
* 3.参考博客:https://www.liuchuo.net/archives/4648
**/
#include <iostream>
#include <algorithm>
#include <cctype>
#include <vector>
#include <unordered_map>
using namespace std;
//学校姓名、加权总分、参赛人数
struct node {
string school;
int tws, ns;
};
//首先按加权总分排行
//如有并列,则应对应相同的排名,并按考生人数升序输出
//如果仍然并列,则按单位码的字典序输出。
bool cmp(node a, node b) {
if (a.tws != b.tws)
return a.tws > b.tws;
else if (a.ns != b.ns)
return a.ns < b.ns;
else
return a.school < b.school;
}
int main() {
int n;
scanf("%d", &n);
//存储某学校名称对应的参赛人数
//unordered_map元素在内部不以任何特定顺序排序,而是组织进桶中。元素放进哪个桶完全依赖于其键的哈希
unordered_map<string, int> cnt;
//计算某学校名称对应的总加权成绩
unordered_map<string, double> sum;
for (int i = 0; i < n; i++) {
string id, school;
cin >> id;
double score;
scanf("%lf", &score);
cin >> school;
//每次学校名称string school都要转化为全小写
for (int j = 0; j < school.length(); j++)
school[j] = tolower(school[j]);
if (id[0] == 'B')
score = score / 1.5;
else if (id[0] == 'T')
score = score * 1.5;
sum[school] += score;
cnt[school]++;
}
//将map中所有学校都保存在vector ans中
vector<node> ans;
for (auto it = cnt.begin(); it != cnt.end(); it++)
ans.push_back(node{it->first, (int)sum[it->first], cnt[it->first]});
//对ans数组排序
sort(ans.begin(), ans.end(), cmp);
//设立pres表示前一个学校的加权总分
int rank = 0, pres = -1;
printf("%d\n", (int)ans.size());
for (int i = 0; i < ans.size(); i++) {
//如果pres和当前学校的加权总分不同
//说明rank等于数组下标+1
if (pres != ans[i].tws) rank = i + 1;
pres = ans[i].tws;
printf("%d ", rank);
cout << ans[i].school;
printf(" %d %d\n", ans[i].tws, ans[i].ns);
}
return 0;
}
1085 PAT单位排行
最新推荐文章于 2021-03-11 13:10:39 发布