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

解题思路:按照平均成绩,C语言成绩,数学成绩,外语成绩依次排序,然后记录排名最好的成绩,利用一个map查询当前这个人是否在输入的数据中。很繁琐,我恨透了这样的题,但是请把它做出来了再骂!
女子为好,先骂为敬。我透!

#include <cstdio>
#include <cstring>
#include <map>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 1000005;
const int maxx = 2018;

struct E{
    int name;
    int a,c,m,e,best;
    int grade[4]; //0-3来记录每一科的排名 
    char item;
    E(){  //构造函数用来初始化的 
        best = maxx;
        item = 'G';
    }
}s[maxx]; 

bool cmp0(E a,E b){
    if(a.a != b.a) return a.a >b.a;
}
bool cmp1(E a,E b){
    if(a.c != b.c) return a.c >b.c;
}
bool cmp2(E a,E b){
    if(a.m != b.m) return a.m >b.m;
}
bool cmp3(E a,E b){
    if(a.e != b.e) return a.e >b.e;
}

int main(){
    int n,m;
    map<int,int> mp; 
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d%d%d%d",&s[i].name,&s[i].c,&s[i].m,&s[i].e);
        s[i].a=int((s[i].c+s[i].m+s[i].e)/3.0+0.5); //四舍五入 
        mp[s[i].name] = i;
    }
    sort(s,s+n,cmp0); //先排平均成绩 
    s[0].grade[0] = 1;
    s[0].best = 1;
    s[0].item = 'A';
    for(int i=1;i<n;i++){
        if(s[i-1].a == s[i].a){
            s[i].grade[0]=s[i-1].grade[0];
        }else{
            s[i].grade[0]=i+1;
        }
        if(s[i].grade[0]<s[i].best){
            s[i].best = s[i].grade[0];
            s[i].item = 'A';
        }
    }

    sort(s,s+n,cmp1); //再排C语言的成绩 
    s[0].grade[1] = 1;
    if(s[0].item != 'A') s[0].item = 'C';//根据本次排名,如果c语言的第一名,在A平均成绩中没有取得第一名,则赋值给C语言科目 
    if(s[0].best>1) {  //如果第一名在A平均成绩中的排名不及这次,则更新最好排名,并附上科目 
        s[0].best =1;
        s[0].item ='C';
    }
    for(int i=1;i<n;i++){ //对除了第一名的人遍历 
        if(s[i-1].c==s[i].c){  //如果两者成绩相同,则取得相同排名 
            s[i].grade[1]=s[i-1].grade[1];
        }else{
            s[i].grade[1]=i+1; //如果两者成绩不同,则取得前面人数总和的下一个名次。 
        }

        if(s[i].grade[1] < s[i].best){ //如果当前排名比最佳排名更好一些,则更新 
            s[i].best = s[i].grade[1];
            s[i].item = 'C';
        }
    }

    sort(s,s+n,cmp2); //再排数学的成绩 
    s[0].grade[2] = 1;
    if(s[0].item != 'A'&&s[0].item!='C') s[0].item = 'M';
    if(s[0].best>1) {
        s[0].best =1;
        s[0].item ='M';
    }
    for(int i=1;i<n;i++){
        if(s[i-1].m==s[i].m){
            s[i].grade[2]=s[i-1].grade[2];
        }else{
            s[i].grade[2]=i+1;
        }
        if(s[i].grade[2]<s[i].best){
            s[i].best = s[i].grade[2];
            s[i].item = 'M';
        }
    }

    sort(s,s+n,cmp3); //最后排英语的成绩 
    s[0].grade[3] = 1;
    if(s[0].item != 'A'&&s[0].item!='C'&&s[0].item !='M') s[0].item = 'E';
    if(s[0].best>1) {
        s[0].best =1;
        s[0].item = 'E';
    }
    for(int i=1;i<n;i++){
        if(s[i-1].e==s[i].e){
            s[i].grade[3]=s[i-1].grade[3];
        }else{
            s[i].grade[3]=i+1;
        }
        if(s[i].grade[3]<s[i].best){
            s[i].best = s[i].grade[3];
            s[i].item = 'E';
        }
    }


    int query;
    for(int i=0;i<m;i++){
        scanf("%d",&query);
        if(mp.find(query)==mp.end()){ //用了一下map方便查询,其实也可以用哈希 
            printf("N/A\n");
            continue;
        }
        for(int i=0;i<n;i++){ //这里又遍历了一遍感觉时间复杂度有点大了 但是还是过了 题目的限制很宽松 
            if(s[i].name == query){
                printf("%d %c\n",s[i].best,s[i].item);
                break;
            }

        }   
    }
    return 0;
}