PAT A1012. The Best Rank
Time Limit: 400ms Memory Limit:65636 KB
题目描述(原题为英文):
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:
(机翻:为了评估我们CS专业一年级学生的表现,我们考虑他们的成绩
三门课程:C -C编程语言,M -数学(微积分或线性代数),
和E -英语。同时,我们鼓励学生强调他们最好的排名-
也就是说,在四个排名中,关于三门课程和平均成绩,我们打印
每个学生最好的排名。
例如,C,M,E和A的成绩——4个学生的平均成绩:)
| 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.I 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.
输入格式
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.
(机翻:每个输入文件包含一个测试用例。每一种情况都以包含2个数字N和M(≤2000),N为学生总数,M为要检查的学生人数,第一行输入N,M,之后的N行,每一行包含一个6位数字组成的学生ID,然后是该学生的三个整数成绩(范围是[0,100]),顺序是C,M,E, 然后是M行,每一行包含一个学生号。)
输出格式
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".
(为M的每一个学生,在一行中打印出他/她的最好的排名,和符号
对应的秩,用空格隔开。
排序方法的优先级按A> C> M >排序
一个学生有更多的方法来获得同样的最佳排名,输出一个最优先级最高的。
如果学生不在评分名单上,只需输出“N/ a”)
输入样例
56 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
输出样例:
1C
1M
1E
1A
3A
N/A
题意:
现已知n个考生的3门课分数C、M、E,而平均分数A可以由这3个分数得到。现在
分别按这4个分数对n个考生从高到低排序,这样对每个考生来说,就会有4个排名且每个
分数都会有一个排名。接下来会有m个查询,每个查询输入一个考生的ID,输出该考生4
个排名中最高的那个排名及对应是A、C、M、E中的哪一个。如果对不同课程有相同排名的
情况,则按优先级A>C>M>E输出;如果查询的考生ID不存在,则输出N/A。
样例解释
| studentID | C | M | E | A | highestrank |
| 310101 | 98(1) | 85(5) | 88(4) | 90(2) | 1C |
| 310102 | 70(5) | 95(1) | 88(4) | 84(5) | 1M |
| 310103 | 82(4) | 87(4) | 941() | 88(3) | 1E |
| 310104 | 91(2) | 91(2) | 91(2) | 91(1) | 1A |
| 310105 | 85(3) | 90(3) | 90(3) |
88(3) |
3A |
思路:
步骤1:考虑到优先级为A>C>M>E,不妨在设置数组时就按这个顺序分配序号为0、
3的元素,即0对应A、1对应C、2对应M及3对应E。
以结构体类型Shudeont存放6位整数的ID和4个分数(grade[0]~grade[3]分别代表A、C、
M、E)。
由于ID是6位的整数,因此不妨设置Rank[1000000][4]数组,其中Rank[id][0]~Rank[id][3]
表示编号为ID的考生的4个分数各自在所有考生中的排名。
步骤2:读入考生的ID和3个分数,同时计算平均分A。
按顺序枚举A、C、M、E,对每个分数,将所有考生排序,并在Rank数组中记录排名。
在查询时,对读入的查询D,先看其是否存在(可通过Rank[id]的初值做判定)。如果存
在,选出Rank[id][0]~Rank[id][3]中数字最小(即排名最高)的那个即可。
时间复杂度为O(nlogn)。
注意点:
①要注意优先级顺序是A>C>M>E,所以为了方便枚举,在设置数组时尽量把A放
在C、M、E前面。
②排名时,相同分数算作排名相同,所以91、90、88、88、84的排名应该算作1、2、
3、3、5。在具体实现时,切记不要算作1、2、3、3、4,否则中间3个测试点至少会错一个。
③ID是整数,不会是字符型。
四舍五入。但本题采用向下取整的方式也能通过,或者采用更简洁的方式一—不取平均,直
④本题没有明示平均分是否需要取整以及取整方式,根据题目描述中的例子可以看出是
接存储三门课的总分。
参考代码:
#include<cstdio> #include<algorithm> #include<cmath> using namespace std; struct Student { int grade[4];//分别记录A,C,M,M四门的成绩。 int id; }stu[2010];//建立一个Student结构体 char course[4] = {'A','C','M','E'}; int n, m,now; int Rank[10000][4] = { 0 };//* bool cmp(Student a, Student b) { return a.grade[now] > b.grade[now];//分高的在前面 } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d%d%d%d", &stu[i].id, &stu[i].grade[1], &stu[i].grade[2], &stu[i].grade[3]); stu[i].grade[0] = round((stu[i].grade[1] + stu[i].grade[2] + stu[i].grade[3])/3.0);//利用round函数求平均值(四舍五入)。 } for (now = 0; now < 4; now++) {//枚举A,C,M,E科 sort(stu, stu + n, cmp);//分数从大到小排序 Rank[stu[0].id][now] = 1;//先将分数最高的考生的此科排名设为1; for (int j = 1; j < n; j++) { if (stu[j].grade[now] == stu[j - 1].grade[now]) { Rank[stu[j].id][now] = Rank[stu[j - 1].id][now];//与上一个学生的分数相同 } else { Rank[stu[j].id][now] = j + 1;//分数不同时 } } } int search;//要查询的考生id for(int i=0;i<m;i++){ scanf("%d", &search); if (Rank[search][0] == 0) { printf("N/A\n"); } else { int k=0; for (int j = 0; j < 4; j++) { if (Rank[search][j] < Rank[search][k]) { k = j;//找到四科里面排名最靠前的,输出 } } printf("%d %c\n",Rank[search][k],course[k]); } } return 0; }

浙公网安备 33010602011771号