我的思路是:结构体排序+二分查找
值得注意的是:1.名次的算法 如 99、 99 、98 对应的排名是1 、1、3; 2.选取的是个人的最佳排名;3.排序函数,参考别人的写法还可以这样写,减少代码量
struct Stu{ int id; int score[4];//a,c,m,e int rk[4]; }; //全局变量pos,迭代pos控制对那门课进行排序 bool cmp1(Stu&a, Stu& b) { return a.score[pos] > b.score[pos]; }
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#define MAXN 2010
using namespace std;
struct Stu{
int id;
int c,m,e,a;
int c_rank,m_rank,e_rank,a_rank;
};
struct Stu stu[MAXN];
bool cmp(Stu&a,Stu&b){
return a.id<b.id;
}
bool cmp0(Stu&a,Stu&b){
return a.a>b.a;
}
bool cmp1(Stu&a,Stu&b){
return a.c>b.c;
}
bool cmp2(Stu&a,Stu&b){
return a.m>b.m;
}
bool cmp3(Stu&a,Stu&b){
return a.e>b.e;
}
void work(Stu&s){
string dis="ACME";
int pos=0,rk=s.a_rank;
if(s.c_rank<rk){
rk=s.c_rank;
pos=1;
}
if(s.m_rank<rk){
rk=s.m_rank;
pos=2;
}
if(s.e_rank<rk){
rk=s.e_rank;
pos=3;
}
cout<<rk<<" "<<dis[pos]<<endl;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>stu[i].id>>stu[i].c>>stu[i].m>>stu[i].e;
stu[i].a=round(1.0*(stu[i].c+stu[i].m+stu[i].e)/3);
}
//排序
sort(stu,stu+n,cmp0);
for(int i=0,rk=1;i<n;i++){
if(i==0){
stu[i].a_rank=1;
}
else{
if(stu[i].a<stu[i-1].a)rk=i+1;
stu[i].a_rank=rk;
}
}
sort(stu,stu+n,cmp1);
for(int i=0,rk=1;i<n;i++){
if(i==0){
stu[i].c_rank=1;
}
else{
if(stu[i].c<stu[i-1].c)rk=i+1;
stu[i].c_rank=rk;
}
}
sort(stu,stu+n,cmp2);
for(int i=0,rk=1;i<n;i++){
if(i==0){
stu[i].m_rank=1;
}
else{
if(stu[i].m<stu[i-1].m)rk=i+1;
stu[i].m_rank=rk;
}
}
sort(stu,stu+n,cmp3);
for(int i=0,rk=1;i<n;i++){
if(i==0){
stu[i].e_rank=1;
}
else{
if(stu[i].e<stu[i-1].e)rk=i+1;
stu[i].e_rank=rk;
}
}
//对id排序以便查找
sort(stu,stu+n,cmp);
// cout<<stu[0].id<<" "<<stu[1].id<<endl;
for(int i=0;i<m;i++){
int id;
cin>>id;
//二分查找
int left=0,right=n-1;
while(left<right){
int mid=(left+right)/2;
if(stu[mid].id<id) left=mid+1;
else right=mid;
}
// printf("left=%d,stu[left].id=%d,id=%d\n",left,stu[left].id,id);
if(stu[left].id!=id) cout<<"N/A"<<endl;
else work(stu[left]);
}
return 0;
}