PAT A1025 PAT Ranking (25)

PAT A1025 题目链接

这道题目的考点是排序

题目大意是输入考场数每个考场的考生数每个考场的考生的编号和成绩,输出考生人数排名

其中,排名包括了考生的编号总排名考场号考场排名

考虑到考场数不超过100,单个考场考生数不超过300,在这道题中我定义了两种结构体,总数分别是30530005。(下面分别称之为结构体A结构体B

其中,结构体A中的数据是会不断更改的,假设某一个考场有n个学生,那么只会对"[0]~[n-1]"进行操作,这些数据换一个考场会更改一次。

对该考场(结构体A)中的这n个学生(下标为[0]~[n-1])进行排序获得考场排名后,将数据存到结构体B中。对每个考场进行相同的操作,这时所有考试的数据都会存放在结构体B中,但还没有总排名。这时,对结构体B进行排序即可。

其中,可通过头文件"#include <algorithm>"中的sort()函数对结构体进行排序,排序规则自定义即可。

注意:
1、要考虑排名并列的情况。例如,只有2个考生,都是95分,则他们并列第1。
2、要考虑在并列排名后下一个排名的情况。例如,有2个考生考了95分,1个考生考了93分。考了93分这个考生的排名是第3,而不是第2。

实现代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

#define MAX1 305
#define MAX2 30005

struct Student1{
	string id;
	int score, locID, locRank;	//不需要总排名,记录考场排名即可
}stu1[MAX1];

struct Student2{
	string id;
	int score, finRank, locID, locRank;
}stu2[MAX2];

bool cmp1(Student1 a, Student1 b){
	if(a.score != b.score) return a.score > b.score;
	else return a.id < b.id;
}

bool cmp2(Student2 a, Student2 b){
	if(a.score != b.score) return a.score > b.score;
	else return a.id < b.id;
}

int main() {
	int n, m, count = 0;
	cin >> n;
	for(int i = 0; i < n; i++){	//n个考场 
		cin >> m;
		for(int j = 0; j < m; j++){
			cin >> stu1[j].id >> stu1[j].score;
			stu1[j].locID = i + 1;
		}
		sort(stu1, stu1 + m, cmp1);	//按成绩排序 
		stu1[0].locRank = 1;	//单独设置第一名 
		for(int j = 1; j < m; j++){	//第i个考场有m个考生 
			if(stu1[j].score == stu1[j-1].score){
				stu1[j].locRank = stu1[j-1].locRank;	//并列 
			}
			else{
				stu1[j].locRank = j + 1;	//后续排名 
			}
		}
		for(int j = 0; j < m; j++){
			stu2[count].id = stu1[j].id;
			stu2[count].score = stu1[j].score;
			stu2[count].locID = stu1[j].locID;
			stu2[count].locRank = stu1[j].locRank;
			count++;
		}
	}
	sort(stu2, stu2 + count, cmp2);		//对所有考生进行排序
	cout << count << endl;
	stu2[0].finRank = 1;
	cout << stu2[0].id << " " << stu2[0].finRank << " " << stu2[0].locID << " " << stu2[0].locRank << endl;
	for(int i = 1; i < count; i++){
		if(stu2[i].score == stu2[i-1].score){
			stu2[i].finRank = stu2[i-1].finRank;
		}
		else{
			stu2[i].finRank = i + 1;
		}
		cout << stu2[i].id << " " << stu2[i].finRank << " " << stu2[i].locID << " " << stu2[i].locRank;	//输出排名情况
		if(i != count - 1){
			cout << endl;
		}
	}
	return 0;
}


氷鸢鸢鸢
2020.3.2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值