题目大意
输入:
N,M——N是考生总人数,M是需要check成绩的人数
依次输入id,C,M,E成绩
再输入需要check成绩的人的id
输出:
需要check成绩的人的最高排名,及其最高排名的科目(按A>C>M>E)的优先级输出。
一开始的大致思路
构建结构体,包含id,A,C,M,E的成绩和排名。
依次比较成绩,然后得出排名
再根据个人排名得出最好的名次和科目。
根据输入的需要check成绩的人的id,对比保存的信息,查看是否属于保存信息的考生。
如果是,输出名次+科目
如果不是,输出N/A
结果:答案全部错误
借鉴了一下柳神的代码,发现柳神的成绩和排名使用了数组保存,即score[]和rank[],这样的话比较成绩和得出排名只需要一个函数就可以解决,同时设定了best这个函数,通过0代表A,1代表C,2代表M,3代表E。
结果还是答案错误。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Student{
char id[8];
int score[4];
int RANK[4];
int best=0;
}stu[100010];
int flag=-1;
bool cmp(Student a,Student b){
return a.score[flag]>b.score[flag];
}
int PAK(Student a){
int min=a.RANK[0];
int j;
for(j=1;j<=3;j++){
if(a.RANK[j]<min){
min=a.RANK[j];
a.best=j;
}
}
return j;
}
int main(){
int N,M;
scanf("%d %d\n",&N,&M);
for(int i=0;i<N;i++){
scanf("%s %d %d %d\n",stu[i].id,&stu[i].score[1],&stu[i].score[2],&stu[i].score[3]);
stu[i].score[0]=(stu[i].score[1]+stu[i].score[2]+stu[i].score[3])/3;
}
for(flag=0;flag<=3;flag++){
sort(stu,stu+N,cmp);
stu[0].RANK[flag]=1;
for(int i=1;i<N;i++){
if(stu[i].score[flag]==stu[i-1].score[flag]){
stu[i].RANK[flag]=stu[i-1].RANK[flag];
}
stu[i].RANK[flag]=i+1;
}
}
char name[M][8];
for(int j=0;j<M;j++){
scanf("%s\n",&name[j][8]);
}
for(int j=0;j<M;j++){
for(int i=0;i<N;i++){
if(strcmp(stu[i].id,name[j])==0){
int x;
x=PAK(stu[i]);
if(x==0) printf("%d %c\n",stu[i].RANK[0],'A');
else if(x==1) printf("%d %c\n",stu[i].RANK[1],'C');
else if(x==2) printf("%d %c\n",stu[i].RANK[2],'M');
else printf("%d %c\n",stu[i].RANK[3],'E');
}
printf("N/A\n");
}
}
return 0;
}
最后只好用柳神的代码提交惹。
然后我自己在后面注释了一下思路。
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
int id,best;
int score[4],rank[4];
}stu[2005];
int exist[10000000],flag=-1;
bool cmp(node a,node b){ //通过flag,使用一个函数,比较四门分数
return a.score[flag]>b.score[flag];
}
int main(){
int n,m,id;
scanf("%d %d\n",&n,&m); //n个考生,m个需要复查的人
for(int i=0;i<n;i++){
scanf("%d %d %d %d\n",&stu[i].id,&stu[i].score[1],&stu[i].score[2],&stu[i].score[3]); //依次输入考生信息
stu[i].score[0]=(stu[i].score[1]+stu[i].score[2]+stu[i].score[3])/3.0;//求平均值
}
for(flag=0;flag<=3;flag++){ //依次求出A,C,M,E的排名
sort(stu,stu+n,cmp);
stu[0].rank[flag]=1; //第一名需要单独提出
for(int i=1;i<n;i++){
if(stu[i].score[flag]==stu[i-1].score[flag]){ //如果i和i-1的分数相等,则排名相等。因为是从第二名开始排,所以i从1开始
stu[i].rank[flag]=stu[i-1].rank[flag];
}
stu[i].rank[flag]=i+1; //不相等的话,排名=下标+1
}
}
for(int i=0;i<n;i++){ //保存已有的所有考生id,同时求出最好的排名,因为按照A,C,M,E的顺序保存排名,所以依次比较就可以按优先级求出最高的排名
exist[stu[i].id]=i+1; //数组[id]=id+1
stu[i].best=0; //假设A的排名最高
int min=stu[i].rank[0];
for(int j=1;j<=3;j++){
if(stu[i].rank[j]<min){
min=stu[i].rank[j]; //替换为排名更高的科目
stu[i].best=j; //同时求出排名最高的科目是什么.0代表A,1代表C,2代表M,3代表E。
}
}
}
char c[5]={'A','C','M','E'};
for(int i=0;i<m;i++){
scanf("%d",&id); //输入需要复查的id
int temp=exist[id]; //在存在数组中查找值,如果temp==0的话,则没有该id。
if(temp){
int best=stu[temp-1].best; //因为temp=exist[id],而exist[id]=id+1,所以temp=id+1
printf("%d %c\n",stu[temp-1].rank[best],c[best]);
}else printf("N/A\n");
}
return 0;
}
最后还有两个点是答案错误的,我有点小崩溃惹。