PAT A 1012 The best Rank

本文探讨了在C++中实现学生考试成绩排名的算法,通过结构体存储学生信息,包括ID和各科成绩,利用排序和比较函数确定每个学生的排名,并找出其最优科目。文章详细介绍了算法步骤,包括输入学生数据、计算排名和输出最佳科目及排名的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

输入:

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;
}

最后还有两个点是答案错误的,我有点小崩溃惹。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值