A1012 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

题意:

第一行给出两个数字 N 和 M(<= 2000),给出N个考生的3门课分数C、M、E,平均分A可以由这三个分数得到。分别按照这4个分数对这N个学生进行排序,对于每个考生而言,就会有一个排名。

接下来有M个查询,每个查询出入考生的ID,输出该考生4个排名中最高的那个以及对应时A、C、M、E中哪一个,如果不同类别有相同排名,优先级按照 A > C > M > E, 如果ID不存在,输出 N/A .

注意:

  1. 本题涉及的量较多,而且要进行多次比较和存储,较难,好麻烦
  2. 定义结构体Student存储6位正数ID、4个分数(A、C、M、E),定义Rank[1000000][4]数组,存储排名,Rank[id][0] - Rank[id][3] 存储编号为 id 的考生四个分数的排名,这种方法很巧妙
  3. 排名时,遇到相同分数,名词相同,后面名次往后推
  4. 本题并未明说平均分是否需要取整以及取整方式,此处直接采用总分进行排序即可
  5. 定义course 数组来分别对应不同类别的分数
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

struct Student{
  int id;
  int grade[4];
}stu[2010];

char course[4] = {'A', 'C', 'M', 'E'};
int Rank[1000000][4] = {0};
int now;

bool cmp(Student a, Student b){
  return a.grade[now] > b.grade[now];
}

int main(){
  int n, m;
  scanf("%d %d", &n, &m);
  for(int i = 0; i < n; i++){
    scanf("%d %d %d", &stu[i].id, &stu[i].grade[1], &stu[i].grade[2], &stu[i].grade[3]);
    stu[i].grade[0] = stu[i].grade[1] + stu[i].grade[2] + stu[i].grade[3];
  }
  for(now = 0; now < 4; now++){
    sort(stu, stu + n, cmp);
    Rank[stu[0].id][now] = 1;
    for(int i = 1; i < n; i++){
      if(stu[i].grade[now] == stu[i - 1].grade[now]){
        Rank[stu[i].id][now] = Rank[stu[i - 1].id][now];
      }
      else{
        Rank[stu[i].id][now] = i + 1;
      }
    }
  }
  int query;
  for(int i = 0; i < m; i++){
    scanf("%d", &query);
    if(Rank[query][0] == 0){
      printf("N/A\n");
    }
    else{
      int k = 0;
      for(int j = 0; j < 4; j++){
        if(Rank[query][j] < Rank[query][k])
          k = j;
      }
      printf("%d %c\n", Rank[query][k], course[k]);
    }
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_35093872/article/details/86555138
今日推荐