1012. The Best Rank (25)

题目链接:http://www.patest.cn/contests/pat-a-practise/1012

题目:

 
  
  
  
  
时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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 Algebra), 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 C, M, E 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

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.

Output

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

 

分析:

题目要求对于一个学生的各项成绩记录,输出每位同学的最好成绩排名和相应科目(并且科目也有优先级:平均成绩高于电脑成绩,高于数学成绩,高于英语成绩)。而注意到,一个单一的排序算法只能找出每位同学某一项或某一方面的成绩好坏,所以需要有多个排序函数,进行多次排序,并且还要记录每次排序后每位同学的各科目排名。

注意点:是会有同分的情况,所以针对99 99 88 88 85的情况,实际排名应该是1 1 3 3 5。而不是1 2 3 4 5或1 1 2 2 3。

案例分析:

对于5条记录(5位同学)的6条查询。

名字  电脑 数学 英语 平均  结果

310101  1 5 4 2 输出的应该是1 C

310102  5 1 4 5   输出1 M

310103  4 4 1 4   输出1 E

310104  2 2 2 1   输出1 A

310105  3 3 3 3   输出 3 A

999999  不存在   输出 N/A



AC代码:

 

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
struct Student{
 int num;
 int name;
 int C_score;
 int M_score;
 int E_score;
 int A_score;
}buf[2001];//学生结构体,存储各项分数和名字
int ans[2001][4];//*用来存储各学生各项分数的排名
char c[4] = {
 'C','M','E','A'
};
int str;
bool cmp1(Student S1,Student S2){
 return (S1.C_score > S2.C_score);
}//电脑分数的排序方法
bool cmp2(Student S1,Student S2){
 return (S1.M_score > S2.M_score);
}//数学分数的排序方法
bool cmp3(Student S1,Student S2){
 return (S1.E_score > S2.E_score);
}//英语分数的排序方法
bool cmp4(Student S1,Student S2){
 return (S1.A_score > S2.A_score);
}//平均分数的排序方法
int main(void){
 int n,m,i;
 while(scanf("%d%d",&n,&m) != EOF){
  for(i = 0; i < n; i ++){
   scanf("%d%d%d%d",&buf[i].name,&buf[i].C_score,&buf[i].M_score,&buf[i].E_score);
   buf[i].A_score = (buf[i].C_score + buf[i].M_score + buf[i].E_score ) / 3;//计算出平均成绩
   buf[i].num = i;
  }//接收数据
  sort(buf, buf + n, cmp1);//按电脑分数高低进行排序
  ans[buf[0].num][0] = 1;
  for(i = 1; i < n; i ++){
   if(buf[i].C_score == buf[i - 1].C_score){
    ans[buf[i].num][0] = ans[buf[i - 1].num][0];
   }//如果分数相同,则和前面同学的排名相同
   else ans[buf[i].num][0] = i + 1;
  }//每位学生电脑成绩的排名
  sort(buf, buf + n, cmp2);//按数学分数高低进行排序
  ans[buf[0].num][1] = 1;
  for(i = 1; i < n; i ++){
   if(buf[i].M_score == buf[i - 1].M_score){
    ans[buf[i].num][1] = ans[buf[i - 1].num][1];
   }//如果分数相同,则和前面同学的排名相同
   else ans[buf[i].num][1] = i + 1;
  }//每位学生数学成绩的排名
  sort(buf, buf + n, cmp3);//按英语分数高低进行排序
  ans[buf[0].num][2] = 1;
  for(i = 1; i < n; i ++){
   if(buf[i].E_score == buf[i - 1].E_score){
    ans[buf[i].num][2] = ans[buf[i - 1].num][2];
   }/如果分数相同,则和前面同学的排名相同
   else ans[buf[i].num][2] = i + 1;
  }//每位学生英语成绩的排名
  sort(buf, buf + n, cmp4);//按平均分数高低进行排序
  ans[buf[0].num][3] = 1;
  for(i = 1; i < n; i ++){
   if(buf[i].A_score == buf[i - 1].A_score){
    ans[buf[i].num][3] = ans[buf[i - 1].num][3];
   }/如果分数相同,则和前面同学的排名相同
   else ans[buf[i].num][3] = i + 1;
  }//每位学生平均成绩的排名
  bool flag;
  for(i = 0; i < m; i ++){
   scanf("%d",&str);
   flag = false;//是否存在对应名字的学生的标志
   for(int j = 0; j < n; j ++){
    if(buf[j].name == str){
     int order = buf[j].num;
     if(ans[order][3] <= ans[order][0] && ans[order][3] <= ans[order][1] && ans[order][3] <= ans[order][2]){
//如果该同学平均成绩排名最好
      printf("%d %c\n",ans[order][3],c[3]);
      flag = true;
      break;
     }
     else if(ans[order][0] <= ans[order][1] && ans[order][0] <= ans[order][2]){
//否则如果该同学电脑成绩排名最好
      printf("%d %c\n",ans[order][0],c[0]);
      flag = true;
      break;
     }
     else if(ans[order][1] <= ans[order][2]){
//否则如果该同学数学成绩排名最好
      printf("%d %c\n",ans[order][1],c[1]);
      flag = true;
      break;
     }
     else {//最后就按英语成绩的排名来
      printf("%d %c\n",ans[order][2],c[2]);
      flag = true;
      break;
     }
    }
   }
   if(flag == false){//如果不存在编号
    puts("N/A");
   }
  }
 }
 return 0;
}

1012. The Best Rank (25)_第1张图片

——Apie陈小旭

你可能感兴趣的:(pat)