//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;
}
PAT A1012 The Best Rank 极度依靠书的思路再自己做的。。。不过ac一次过了
最新推荐文章于 2020-05-26 13:19:11 发布