题目链接: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;
}