PAT Advanced 1012 The Best Rank

題目

1012 The Best Rank (25分)

To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algrbra), and E - English. At the mean time, we encourage students by emphasizing on their best ranks -- that is, among the four ranks with respect to the three courses and the average grade, we print the best rank for each student.ios

For example, The grades of C, M, E and A - Average of 4 students are given as the following:c++

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

Then the best ranks for all the students are No.1 since the 1st one has done the best in C Programming Language, while the 2nd one in Mathematics, the 3rd one in English, and the last one in average.git

Input Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N and M (≤2000), which are the total number of students, and the number of students who would check their ranks, respectively. Then N lines follow, each contains a student ID which is a string of 6 digits, followed by the three integer grades (in the range of [0, 100]) of that student in the order of C, M and E. Then there are M lines, each containing a student ID.github

Output Specification:

For each of the M students, print in one line the best rank for him/her, and the symbol of the corresponding rank, separated by a space.算法

The priorities of the ranking methods are ordered as A > C > M > E. Hence if there are two or more ways for a student to obtain the same best rank, output the one with the highest priority.數組

If a student is not on the grading list, simply output N/A.數據結構

Sample Input:

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

Sample Output:

1 C
1 M
1 E
1 A
3 A
N/A

理解與算法

這道題理解起來不難,重點在怎麼實現。ide

寫了三四天的PAT,慢慢有點感受,能用簡單的數據結構就用簡單的數據結構,不要想着一個龐大的結構體包含你須要的全部狀態,這不現實,也不經濟,咱們應該用足夠少的數據量,配合必須的數據容器,來表示所有的信息。lua

我最開始的想法是用四個數組來表示學生們的成績,而咱們須要對數據進行排序,排序完會丟失學生信息的完整性,就算你用四個結構體來綁定學號和成績的信息,仍是會多不少的冗餘信息!spa

因此咱們將學生的信息打包成一個結構體,每次排序以後的排位信息也存儲在這個結構體中,並記錄這個學生哪門課排名最好!

由上述信息咱們這麼設計:

struct student {
    int id;
    int score[4];
    int rank[4];
    int best;
};
  • id 學號,由於學號的長度有限制,因此咱們能夠直接用int類型來存儲,若是再大一點咱們就用long int,這麼作是爲了方便快速存取
  • score 成績信息,爲了對應不一樣科目的優先級,0-3分別爲A,C,M,E,這樣也方便後面計算最佳排名
  • rank 每門課的排位信息,與上述成績score一一對應。
  • best 最好的排名信息,值爲score與rank數組的一個下標。

遇到的一個問題:

因爲存在分數同樣的問題,因此若是直接用下標來表示學生成績的排名就會出現問題,由於同樣的分數就應該是同樣的排名,因此要和前一個學生進行比較,相同則繼承排名!

代碼與實現[1]

//
// Created by tanknee on 2021/1/25.
//

#include <iostream>
#include <algorithm>

using namespace std;

struct student {
    int id;
    int score[4];
    int rank[4];
    int best;
};
student students[2001];

int exists[1000001], flag = -1;

bool cmp1(student a, student b) { return a.score[flag] > b.score[flag]; }

int main() {
    int N, M, id;
    cin >> N >> M;
    for (int i = 0; i < N; ++i) {
        cin >> students[i].id >> students[i].score[1] >> students[i].score[2] >> students[i].score[3];
        students[i].score[0] = (students[i].score[1] + students[i].score[2] + students[i].score[3]) / 3.0 + 0.5;
    }
    // 計算學生每門課程的排名
    for (flag = 0; flag <= 3; flag++) {
        sort(students, students + N, cmp1);
        students[0].rank[flag] = 1;
        for (int i = 1; i < N; ++i) {
            students[i].rank[flag] = i + 1;
            // 若是分數相同,那麼排名也跟以前的同樣
            if (students[i].score[flag] == students[i - 1].score[flag]) {
                students[i].rank[flag] = students[i - 1].rank[flag];
            }
        }
    }
    // 計算每一個學生的最好排名
    for (int i = 0; i < N; ++i) {
        exists[students[i].id] = i + 1;
        students[i].best = 0;
        int min_num = students[i].rank[0];
        for (int j = 1; j <= 3; ++j) {
            if (students[i].rank[j] < min_num) {
                min_num = students[i].rank[j];
                students[i].best = j;
            }
        }
    }
    char tmp_chars[5] = {'A', 'C', 'M', 'E'};
    for (int i = 0; i < M; ++i) {
        cin >> id;
        int tmp = exists[id];
        if (tmp) {
            int best = students[tmp - 1].best;
            cout << students[tmp - 1].rank[best] << " " << tmp_chars[best] << endl;
        } else {
            cout << "N/A" << endl;
        }
    }
    return 0;
}

  1. https://github.com/liuchuo/PAT ↩︎

相關文章
相關標籤/搜索