【PAT甲级题解记录】1012 The Best Rank (25 分)
前言
Problem:1012 The Best Rank (25 分)
Tags:结构体排序 映射
Difficulty:
剧情模式想流点汗想流点血死而无憾Address:1012 The Best Rank (25 分)
问题描述
一个学生有三门课的成绩以及一个平均分成绩,分别用A、C、M、E表示。
每一个学生都有一个 best ranks – 最好排名,指的是四个成绩里取排名最高的成绩,求每个学生的最好排名以及是哪门成绩(若最好排名的成绩可以是不同的学科,按照ACME顺序优先输出)。
解题思路
- 一个学生有四个成绩,用一个结构体或者类存储会比较方便,又考虑到每个成绩都需要排名,结构体内应还有四个成绩的排名值、最好排名的课程号以方便查询。
- 对四个成绩分别排序以此初始化所有学生的四个成绩的排名值。(小技巧:利用stl的sort排序结构体需要自定义cmp()函数,可以设置全局变量或者类内静态变量从而自定义地确定cmp的排序方式)
- 小坑点:会出现排名并列的情况,所以第2步中初始化排名值时需要先比较前一名学生的成绩。
- 为了方便询问,用一个map映射一个Student(其实一个数组就可以了),然后比较四个成绩排名值即可。
参考代码
1. 结构体实现
/*
* @Author: Retr0.Wu
* @Date: 2022-02-16 02:18:22
* @Last Modified by: Retr0.Wu
* @Last Modified time: 2022-02-16 02:18:22
*/
#include <cstdio>
#include <algorithm>
using namespace std;
struct node
{
int id, best;
int score[4], rank[4];
} stu[2005];
int exist[1000000], flag = -1;
bool cmp1(node a, node b)
{
return a.score[flag] > b.score[flag];
}
int main()
{
int n, m, id;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++)
{
scanf("%d %d %d %d", &stu[i].id, &stu[i].score[1], &stu[i].score[2], &stu[i].score[3]);
stu[i].score[0] = (stu[i].score[1] + stu[i].score[2] + stu[i].score[3]) / 3.0 + 0.5;
}
for (flag = 0; flag <= 3; flag++)
{
sort(stu, stu + n, cmp1);
stu[0].rank[flag] = 1;
for (int i = 1; i < n; i++)
{
stu[i].rank[flag] = i + 1;
if (stu[i].score[flag] == stu[i - 1].score[flag])
stu[i].rank[flag] = stu[i - 1].rank[flag];
}
}
for (int i = 0; i < n; i++)
{
exist[stu[i].id] = i + 1;
stu[i].best = 0;
int minn = stu[i].rank[0];
for (int j = 1; j <= 3; j++)
{
if (stu[i].rank[j] < minn)
{
minn = stu[i].rank[j];
stu[i].best = j;
}
}
}
char c[5] = {'A', 'C', 'M', 'E'};
for (int i = 0; i < m; i++)
{
scanf("%d", &id);
int temp = exist[id];
if (temp)
{
int best = stu[temp - 1].best;
printf("%d %c\n", stu[temp - 1].rank[best], c[best]);
}
else
{
printf("N/A\n");
}
}
return 0;
}
2. 类实现
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
class Student {
public:
string id;
int best_course;
vector<int> score;
vector<int> rank;
static int sort_type;
};
int N, M;
vector<Student> students;
map<string, int> id_to_index;
int Student::sort_type = 0;
bool cmp(Student &s1, Student &s2) {
return s1.score[Student::sort_type] > s2.score[Student::sort_type];
}
void init() {
cin >> N >> M;
students.resize(N);
for (int i = 0; i < N; ++i) {
Student s;
s.score.resize(4, 0);
s.rank.resize(4, 0);
cin >> s.id >> s.score[1] >> s.score[2] >> s.score[3];
s.score[0] = (s.score[1] + s.score[2] + s.score[3]) / 3;
students[i] = s;
}
// 按照四个成绩分别排个序
for (Student::sort_type = 0; Student::sort_type < 4; Student::sort_type++) {
sort(students.begin(), students.end(), cmp);
// update 4 ranks of students
students[0].rank[Student::sort_type] = 0;
for (int i = 1; i < N; i++) {
int pre_score = students[i - 1].score[Student::sort_type];
int now_score = students[i].score[Student::sort_type];
students[i].rank[Student::sort_type] = pre_score == now_score ? i - 1 : i;
}
}
// 干两件事,一是完成id到学生在数组中位置的映射(id_to_index),二是初始化学生的最好排名是哪一门课(best_course)
for (int i = 0; i < N; ++i) {
id_to_index[students[i].id] = i;
int best_course = 0;
for (int j = 1; j < 4; ++j) {
if (students[i].rank[j] < students[i].rank[best_course]) {
best_course = j;
}
}
students[i].best_course = best_course;
}
}
void solve() {
string ACME = "ACME";
for (int i = 0; i < M; ++i) {
string id;
cin >> id;
if (id_to_index.count(id) == 0) {
cout << "N/A" << endl;
continue;
}
int index = id_to_index[id];
int best_course = students[index].best_course;
cout << students[index].rank[best_course] + 1 << " " << ACME[best_course] << endl;
}
}
void solution_1012() {
init();
solve();
}
int main() {
solution_1012();
return 0;
}