【PAT甲级题解记录】1012 The Best Rank (25 分)

【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顺序优先输出)。

解题思路

  1. 一个学生有四个成绩,用一个结构体或者类存储会比较方便,又考虑到每个成绩都需要排名,结构体内应还有四个成绩的排名值、最好排名的课程号以方便查询。
  2. 对四个成绩分别排序以此初始化所有学生的四个成绩的排名值。(小技巧:利用stl的sort排序结构体需要自定义cmp()函数,可以设置全局变量或者类内静态变量从而自定义地确定cmp的排序方式)
  3. 小坑点:会出现排名并列的情况,所以第2步中初始化排名值时需要先比较前一名学生的成绩。
  4. 为了方便询问,用一个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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值