PAT A1012 The Best Rank 极度依靠书的思路再自己做的。。。不过ac一次过了

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值