给出多个学生的 ID 以及 C、M、E 这三门课程的成绩,A 代表 C、M、E 这三门课程的平均成绩。输入一个学生 ID,要求输出该学生的 A、C、M、E 这 4 门成绩在所有学生中最高排名。
先输入 N 和 M,代表有 N 个学生以及 M 个查询。之后的 N 行,每行按“ID C M E”的格式给出一个学生的 ID 以及 C、M、E 这三门课程的成绩。之后 M 行,每行给出一个学生的 ID。
输出 M 行,每行输出给定学生的 A、C、M、E 这 4 门成绩在所有学生中最高排名以及对应科目。如果该 ID 不存在,输出N/A
。
先定义unordered_map<gg, unordered_map<char, gg>> rank
用来存储学生的 ID 以及对应的 ACME 这四科排名。注意这里的 rank 是一个嵌套的 unordered_map,rank 的键是一个 gg 类型,存储学生的 ID;rank 的值又是一个 unordered_map,它的键是一个 char 类型,负责存储 ACME 字符,它的值负责存储该科目的排名。
再定义一个unordered_map<char, vector<pair<gg, double>>> acme
存储四门科目以及对应的所有学生成绩。注意 acme 也是一个 unordered_map,它的键存储 ACME 字符,它的值是一个 vector,存储不同的 pair,这些 pair 的 first 成员是 gg 类型,存储学生的 ID,second 成员是一个 double,存储该学生在该科目上的成绩。注意由于平均成绩可能是小数,因此可以直接将所有成绩均用 double 存储。
读取所有学生的 ID 和成绩并存入 acme 中,针对 acme 中学生成绩进行排序,然后计算每名学生的排名并存入 rank 中。然后针对每个查询,直接在 rank 中查找每个学生的最高排名即可。
具体实现可参考下面的代码。
具有相同成绩的学生应有相同的排名。
#include <bits/stdc++.h>
using namespace std;
using gg = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
gg ni, mi, id, gi;
cin >> ni >> mi;
//学生ID以及对应的ACME排名
unordered_map<gg, unordered_map<char, gg>> rank;
// ACME每科目分别对应的所有学生成绩
unordered_map<char, vector<pair<gg, double>>> acme;
for (gg i = 0; i < ni; ++i) {
cin >> id;
double sum = 0;
for (char c : {'C', 'M', 'E'}) { //读取三门成绩并放入acme中
cin >> gi;
sum += gi;
acme[c].push_back({id, gi});
}
acme['A'].push_back({id, sum / 3.0}); //求平均成绩
}
for (auto& i : acme) {
auto& c = i.first; // c存储当前处理的科目
auto& grade = i.second; // grade处理该科目所有学生的成绩
sort(grade.begin(), grade.end(),
[](const pair<gg, double>& p1, const pair<gg, double>& p2) {
return p1.second > p2.second;
}); //按成绩从大到小排序
gg r = 1;
for (gg j = 0; j < grade.size(); ++j) { //求出所有学生在该科目上的排名
if (j == 0 or abs(grade[j].second - grade[j - 1].second) > 1e-6) {
r = j + 1;
}
rank[grade[j].first][c] = r;
}
}
for (gg i = 0; i < mi; ++i) { //处理m个查询
cin >> id;
if (not rank.count(id)) { // ID不存在
cout << "N/A\n";
continue;
}
char c = 'A';
for (char j : {'A', 'C', 'M', 'E'}) { //求该学生最高排名的科目
if (rank[id][j] < rank[id][c]) {
c = j;
}
}
cout << rank[id][c] << " " << c << "\n";
}
return 0;
}