前言

传送门

正文

参考题解

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
/*
需要得出每个学生的A、C、M、E、四门成绩中排名最高的成绩,
根据输出结果可知需要建立id,排名和课程之间的联系,于是
可用一个二维数组Rank[id][课程]=排名;由于优先级是A>C>M>E,
故设置数组的时候就0对应A,1对应C,2对应M,3对应E。又id是六位数
故设置Rank[1000000][4],其中Rank[id][0]~Rank[id][3]表示编号为
id的学生在该科目下的排名。 

首先读入学生各科成绩数据,注意A为其平均分,四舍五入,可以直接
加上0.5,因为round函数返回值就是参数加上0.5再向下取整 。同时需要注意
Rank数组需要定义为全局变量(静态存储区),若定义为局部变量,因为数组过大则可能会导致栈溢出,
即 process exited with return value 3221225477 。同时需要注意若报错
reference to ' xxx ' is ambiguous  ,则说明xxx变量可能和库函数中的属性或
者方法重名了,需要将xxx改个名字就好了 
 
 这里有个关于排名的坑点尤其需要说明下,相同分数算作排名相同,所以91、90、88。88、84的排名应该
 是1,2,3,3,5而不是1,2,3,3,4
*/
struct student{
	int id;
	int grade[4];
}stu[2020];
int Rank[1000000][4]={0};
char course[4]={'A','C','M','E'}; //课程 
int index=0;//按照哪门课程分数排名 
bool cmp(student a,student b){
	return a.grade[index]>b.grade[index]; //降序排序 
}
int main(){
	int n,m;
	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]=(stu[i].grade[1]+stu[i].grade[2]+stu[i].grade[3])/3.0+0.5;
	}
	for(index=0;index<4;index++){//遍历每门课程进行排序
		sort(stu,stu+n,cmp); 
		Rank[stu[0].id][index]=1;//排到首位的学生该科目为第一
		for(int j=1;j<n;j++){
			if(stu[j].grade[index]==stu[j-1].grade[index]){//如果和上一名分数一样,则排名相同 
				Rank[stu[j].id][index]=Rank[stu[j-1].id][index];
			}else{//如果和上一名分数不一样,则排名为j+1 
				Rank[stu[j].id][index]=j+1; 
			}
		} 
	}
	int queryId;
	for(int i=0;i<m;i++){
		scanf("%d",&queryId);
		if(Rank[queryId][0]==0){//没有该学生的信息 
			printf("N/A\n"); 
		}else{//存在该学生信息,找到其最高的排名以及其对应的科目 
			int highRank=2001,k;
			for(int j=0;j<4;j++){
				if(Rank[queryId][j]<highRank){//最高排名即为排名数最小
					highRank=Rank[queryId][j];
					k=j;
				}
			}
			printf("%d %c\n",highRank,course[k]);
		}
	} 
	return 0;
}