//ac了,Rank必须大写,才能在pat上ac,可能是std中有重名的.小写自己的dev上通过,pat上通不过 //注意:本题用int表示id,想想好处 //依次顺序是ACME,grade和rank都是 //当想要用for循环对数组排序的时候,请用sort #include<stdio.h> #include<string.h> #include<algorithm> //#define LOCAL using namespace std; struct Student{ int id;//之前自己用的char[8],但是这样更加耗内存啊,而且等下查找id的时候不好比较,用int直接比较大小就行了 int grade[4]; }stu[2010]; int now;//全局变量,cmp中使用,表示当前按now号分数排序stu数组 int Rank[1000000][4]={0};//注意是6个0,不要再被带跑了 char course[4]={'A','C','M','E'}; bool cmp(Student a,Student b){ //这里需要用到全局变量了,看仔细!以前从没意识到全局变量的作用呢! return a.grade[now]>b.grade[now];//按照now号的分数递增排序 } int main(){ #ifdef LOCAL freopen("A1012data.in","r",stdin); freopen("A1012data.out","w",stdout); #endif int n,q; scanf("%d %d",&n,&q); //进行四次排序并赋值? 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; }//到这里N个学生成绩输入结束 //下面进行对Rank赋值处理,涉及对n个学生的四个成绩的排序。 //不用担心排序后原来数据变化啊怎么样,因为只要按照学号排,还是会变成原来样子啊! //凡排序,而不是最大最小值,都是需要数组装下所有数据的 for(now=0;now<4;now++){ //这个now也是grade的下标,对这个下标的所有grade进行排序。这时候下标对应的数据是从大道小的了哦! //将分数最大设置为1,后面的如果和前一个一样,那Rank就和前一个一样,若不一样,就是i+1 //根据now的值来确定按照哪个进行从大到小排序 sort(stu,stu+n,cmp); //下面根据排序后的顺序对Rank[now]进行相应赋值 Rank[stu[0].id][now]=1;//stu[0]的该门是排名第一 for(int i=1;i<n;i++){//对剩下的学生 //Rank[stu[i].id][now] if(stu[i].grade[now]==stu[i-1].grade[now]){ Rank[stu[i].id][now]=Rank[stu[i-1].id][now]; } else //如果不是等于0,那就应该是前面一个大于后面一个了! Rank[stu[i].id][now]=i+1;//注意不是i,也不是跟着上面的累计,现在是第几个,就是第几 }//这样对每个学生的now号成绩的Rank就有了 }//每个学生的四门成绩的Rank都有了 int query=0; for(int i=0;i<q;i++){ scanf("%d",&query); if(Rank[query][0]==0){ //如果这个学生不曾被赋值。一开始我以为这里可以比较id的值是否在6位范围内,后来发现不对 //有可能id确实是在6位范围内,但是却在上面没有录入赋值。也不应该被查到 printf("N/A\n"); } else{ int k=0;//选出Rank[query][0~3]中最小的Rank值,值越小,排名越高 for(int j=1;j<4;j++){//注意,这里是按照ACME的顺序的,符合上面的如果两个等级一样,优先级输出 if(Rank[query][j]<Rank[query][k]) k=j; } printf("%d %c\n",Rank[query][k],course[k]); } } return 0; }