PAT-A 1012 The Best Rank (25 分)

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.

For example, The grades of CME and A - Average of 4 students are given as the following:

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.

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 CM and E. Then there are M lines, each containing a student ID.

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

分析:

每个学生有C语言、数学、英语、三门成绩的平均成绩,共4个成绩。

分别按照每一门成绩对学生进行排名,每个学生将有4个排名,取最好的那个排名为最终排名。如果一个学生有两个科目的排名都是最好的排名,那么按照平均成绩>C语言>数学>英语的优先级来确定取得最好排名的科目。比如,一个学生4个成绩排名都是第1,那么认为该学生取得最好排名的是平均成绩,输出时将输出“1 A”。

扫描二维码关注公众号,回复: 4947415 查看本文章

在对某一门成绩进行排序时,如果有两个学生的成绩相同,那么这两个同学在该门成绩中的排名相同。

比如C语言的成绩从高到低为100, 100, 99, 99,98那么排名分别为1, 1, 3, 3, 5.

如果不对成绩相同的学生进行处理,会卡在第1个和第2个测试点,如图:

代码:

#include <cstdio>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;

typedef struct student
{
    string id;
    int c;
    int m;
    int e;
    int a;
    pair<int, char> best;//存储最好的排名和相应科目
    student(string _id, int _c, int _m, int _e, int _a):id(_id), c(_c), m(_m), e(_e), a(_a){}
}stu;

bool cmpByC(stu a, stu b)
{   //按照C语言分数进行排序
    return a.c > b.c;
}

bool cmpByM(stu a, stu b)
{   //按照数学分数进行排序
    return a.m > b.m;
}

bool cmpByE(stu a, stu b)
{   //按照英语分数进行排序
    return a.e > b.e;
}

bool cmpByA(stu a, stu b)
{   //按照平均分数进行排序
    return a.a > b.a;
}

int main()
{
    int N, M;
    scanf("%d %d", &N, &M);

    vector<stu> all;//用来保存所有输入的学生的信息
    map<string, pair<int, char> > result;//保存学生的学号,和学生的最好排名以及代表相应的科目的字符
    char id[7];//保存每次输入的学生的id
    int c, m, e;//保存每次输入的学生的三个分数
    for(int i = 0; i < N; i++)
    {   //输入学生信息,计算平均分,并将所有信息保存到all中
        scanf("%s %d %d %d", id, &c, &m, &e);
        all.push_back(stu(string(id), c, m, e, (c + m + e) / 3));
    }

    int nowRank;//用来处理两个学生同一门科目成绩相同的情形

    sort(all.begin(), all.end(), cmpByA);//先按照平均分进行排名
    for(int i = 0; i < all.size(); i++)
    {
        if(i == 0)
            nowRank = 1;//all[0]的平均分最高,排名自然为1
        else if(all[i].a < all[i - 1].a)
            nowRank = i + 1;//如果当前学生的平均分比前一个学生的平均分低,当前排名才更新
        all[i].best = pair<int, char>(nowRank, 'A');//先将按照平均分进行的排名当做最好排名,后面再进行比较、更新
    }
    sort(all.begin(), all.end(), cmpByC);//再按照C语言分数进行排名
    for(int i = 0; i < all.size(); i++)
    {
        if(i == 0)
            nowRank = 1;
        else if(all[i].c < all[i - 1].c)
            nowRank = i + 1;//所有科目对分数相同者的排名的处理是相同的
        if(all[i].best.first > nowRank)//由于最高排名相同时取优先级高的科目,这里必须是严格大于
            all[i].best = pair<int, char>(nowRank, 'C');//出现更好的排名,更新排名信息
    }
    sort(all.begin(), all.end(), cmpByM);//再按照数学分数进行排序
    for(int i = 0; i < all.size(); i++)
    {
        if(i == 0)
            nowRank = 1;
        else if(all[i].m < all[i - 1].m)
            nowRank = i + 1;
        if(all[i].best.first > nowRank)//由于最高排名相同时取优先级高的科目,这里必须是严格大于
            all[i].best = pair<int, char>(nowRank, 'M');//出现更好的排名,更新排名信息
    }
    sort(all.begin(), all.end(), cmpByE);//再按照英语成绩进行排序
    for(int i = 0; i < all.size(); i++)
    {
        if(i == 0)
            nowRank = 1;
        else if(all[i].e < all[i - 1].e)
            nowRank = i + 1;
        if(all[i].best.first > nowRank)//由于最高排名相同时取优先级高的科目,这里必须是严格大于
            all[i].best = pair<int, char>(nowRank, 'E');//此时已经得到第i个学生的最终排名结果
        result.insert({all[i].id, all[i].best});//将结果存入到result中以待查询,这里使用大括号初始化pair
    }
    for(int i = 0; i < M; i++)
    {
        scanf("%s", id);//输入待查询学生的id
        string tem = string(id);
        if(result.find(tem) == result.end())//没有该学生信息,注意find的返回值
            printf("N/A\n");
        else
            printf("%d %c\n", result[tem].first, result[tem].second);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38127801/article/details/86420261