题目链接:http://www.patest.cn/contests/pat-a-practise/1012
题目:
时间限制400 ms内存限制65536 kB代码长度限制16000 B判题程序Standard作者CHEN, YueTo 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 91Then 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 Input5 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 999999Sample Output1 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; }
——Apie陈小旭