题目:
为了评估我们第一年 CS 专业学生的表现,我们只考虑他们三门课程的成绩:C - C 编程语言、M - 数学(微积分或线性代数)和 E - 英语。同时,我们鼓励学生强调他们最好的排名——即在三个课程和平均成绩的四个排名中,我们为每个学生打印最好的排名。
例如,C、M、E 和 A 的成绩 - 4 名学生的平均成绩如下:
学生证 C M E A
310101 98 85 88 90
310102 70 95 88 84
310103 82 87 94 88
310104 91 91 91 91
然后所有学生的最好成绩是第一名,因为第一名在C程序设计语言方面做得最好,而数学第二名,英语第三名,平均排名最后一名。
输入规格:
每个输入文件包含一个测试用例。每个案例以一行包含 2 个数字 N 和 M(≤2000)开始,分别是学生总数和检查排名的学生人数。然后是N行,每行包含一个6位数的学生ID,后面是该学生的三个整数等级([0, 100]范围内),依次为C、M、E。然后有是 M 行,每行包含一个学生 ID。
输出规格:
对于 M 名学生中的每一个,将他/她的最佳排名和相应排名的符号打印在一行中,并用空格分隔。
排序方法的优先级顺序为 A > C > M > E。因此,如果学生有两种或多种方式获得相同的最佳排名,则输出优先级最高的一种。
如果学生不在评分列表中,只需输出 N/A。
样本输入:
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
示例输出:
1 C
1 M
1 E
1 A
3 A
N/A
题目大意:
给出n个学生的三门分数,平均分得自己求,然后根据四个分数总体比较降序排序,这样每个学生的自己的四个分数都会有排名,找到排名最优的输出,名次相同则按A>C>M>E顺序输出,ID不存在则输出N/A
解题思路:
在结构体里定义两个大小为4的数组,score数组储存学生的四个成绩,另一个储存学生的四个成绩的排名,在输入时同时得出平均分。
而后利用sort对A、C、M、E的成绩分别进行降序排序,每次排序记录每个学生在该成绩的排名是多少,最后进行ID验证输出即可。
注:当出现成绩相同时排名应该也相同,不然会导致有个测试点过不去 如:1 2 3 4 5,如果成绩1与成绩2相同,排名则为1 1 3 4 5。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int flag;
struct student{
int best;
int id;
int score[4];
int rank[4];
};
bool cmp(student a,student b){
//按单个科目分数进行降序排序
return a.score[flag]>b.score[flag];
}
int main()
{
int n,m;
const char z[4]={'A','C','M','E'};
scanf("%d %d",&n,&m);
student stu[2005];
for(int i=0;i<n;i++){
cin>>stu[i].id>>stu[i].score[1]>>stu[i].score[2]>>stu[i].score[3];
//计算平均数
stu[i].score[0]=(stu[i].score[1]+stu[i].score[2]+stu[i].score[3])/3;
stu[i].best=0;
}
for(flag=0;flag<4;flag++){
sort(stu,stu+n,cmp);
for(int j=0;j<n;j++){
//判断如果该学生该成绩与上一名次的学生该成绩一样,则名次也应一样
if(j>=1&&stu[j].score[flag]==stu[j-1].score[flag])stu[j].rank[flag]=stu[j-1].rank[flag];
否则就记录正常名次
else stu[j].rank[flag]=j;
判断学生名次最佳的是哪门课目 记录最佳科目的下标
if(stu[j].rank[flag]<stu[j].rank[stu[j].best])stu[j].best=flag;
}
}
for(int i=0;i<m;i++){
int num;
cin>>num;
for(int j=0;j<n;j++){
if(stu[j].id==num){
//因为记录名次是从0开始记录,所以输出应该+1
printf("%d %c\n",stu[j].rank[stu[j].best]+1,z[stu[j].best]);
break;
}
if(j==n-1){
printf("N/A\n");
}
}
}
return 0;
}
对于最后ID验证也可以在开始的时候记录好ID是否存在并进行相关操作,有些地方可以更好更简洁一些,大体思路差不多吧