题目描述
现在,要给 CS 专业一年级的学生进行成绩评估。
我们只考虑他们的三门成绩:C–c语言,M–数学,E–英语,除此之外,我们还会考虑 A –三门成绩平均值。
注意:平均成绩为三科成绩平均值四舍五入取整的结果。
例如,四个学生的成绩单如下:
StudentID C M E A
310101 98 85 88 90
310102 70 95 88 84
310103 82 87 94 88
310104 91 91 91 91
每个学生都会有各科排名以及平均成绩排名,我们通过强调学生的最佳成绩来鼓励学生。
因此,每个学生的成绩单上只会有四个成绩中排名最高的那个成绩的排名,
以及具体是哪项成绩(C、M、E、A 中的一项)。
例如,第一个学生的成绩单上会显示 1 C,因为他的C语言排名第 1,这是他的最佳名次。
而第四个学生的成绩单上会显示 1 A,因为他的平均成绩排名第 1,这是他的最佳名次。
输入格式
第一行包含两个整数 N,M,分别表示学生总数和查询成绩单次数。
接下来 N 行,每行首先包含一个由六位数字组成的学生 ID,
然后包含三个整数分别表示该学生的 C,M,E 三科成绩。
接下来 M 行,每行包含一个学生 ID,表示要查询该学生的成绩单。
输出格式
对于每个学生,输出他的最佳排名以及该排名对应的是哪项成绩。
当多项排名相同,且都为最佳时,按照 A>C>M>E 的优先级,选择输出哪项成绩。
如果无法查询到该学生的成绩,则输出 N/A。
数据范围
1≤N,M≤2000,
每科成绩均在 [0,100] 之间。
输入样例:
5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
999999
输出样例:
1 C
1 M
1 E
1 A
3 A
N/A
算法1
主要是模拟 题意比较绕。
接受各个学生的三门成绩 然后四舍五入计算出平均成绩
在 接受询问的学生的id后 打印出该学生排名最佳的学科名次和学习名字
如果多门学科名次相同 则按照 ACME的次序排序考虑
这里有个暗坑需要注意的是
如果某学科的成绩排序如下
100
99
99
99
85
那么该科目成绩99的三个学生都是排名第二 成绩85的学生排名第五
所以最好使用数组来记录成绩排序(允许有重复)
然后查询某个成绩的排名使用遍历找到第一个符合的分数的位置就是排名 或者使用二分查找第一个符合分数的位置作为排名
C++ 代码
#include <iostream>
#include <map>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
const int N = 2010;
map<string, vector<int>> mm;
vector<int> mA; vector<int> mC; vector<int> mM; vector<int> mE;
int n, m;
int GetIdxA(int x) {
for (int i = 0; i < mA.size(); i++) { if (x == mA[i]) return i + 1; }
return 0;
}
int GetIdxC(int x) {
for (int i = 0; i < mC.size(); i++) { if (x == mC[i]) return i + 1; }
return 0;
}
int GetIdxM(int x) {
for (int i = 0; i < mM.size(); i++) { if (x == mM[i]) return i + 1; }
return 0;
}
int GetIdxE(int x) {
for (int i = 0; i < mE.size(); i++) { if (x == mE[i]) return i + 1; }
return 0;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
string id; int C, M, E;
cin >> id >> C >> M >> E;
int A = round((C + M + E) / 3.0);
mm[id].push_back(A);
mm[id].push_back(C);
mm[id].push_back(M);
mm[id].push_back(E);
mA.push_back(A); mC.push_back(C);
mM.push_back(M); mE.push_back(E);
}
sort(mA.begin(), mA.end(),greater<int>()); sort(mC.begin(), mC.end(), greater<int>());
sort(mM.begin(), mM.end(), greater<int>()); sort(mE.begin(), mE.end(), greater<int>());
for (int i = 0; i < m; i++) {
string id; cin >> id;
if (mm.count(id) == 0) { cout << "N/A" << endl; continue; }
int ans = 999999; char type = 'A';
int idx = GetIdxA(mm[id][0]);
if (ans > idx) { ans = idx; type = 'A'; }
idx = GetIdxC(mm[id][1]);
if (ans > idx) { ans = idx; type = 'C'; }
idx = GetIdxM(mm[id][2]);
if (ans > idx) { ans = idx; type = 'M'; }
idx = GetIdxE(mm[id][3]);
if (ans > idx) { ans = idx; type = 'E'; }
cout << ans << " " << type << endl;
}
return 0;
}
不用平均分,改用总分排名,把 int A = round((C + M + E) / 3.0); 改为 int A = C + M + E; 会错,为什么