跳过正文
题解:B3968 [GESP202403 五级] 成绩排序

题解:B3968 [GESP202403 五级] 成绩排序

xyx404
作者
xyx404
Have a nice day.

封面

思路:
#

使用结构体快排,自己写判断函数,按照题目给出的进行判断,判断后历遍一次结构体数组,把学生的排名赋值,然后按照输入的顺序再排序一次最后输出就可以了。

如何赋值排名,如果和上一个人的排名是相同的就赋值为上一个人的排名,如果不是直接赋值为 $i$。

代码:
#

// 以下代码与思路完全相同 
// 本代码已经提交测试并且已经 AC 
#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
	long long sum/* 总和 */,chinese/* 语文 */,math/* 数学 */,english/*english 可以不定义在结构体里 */;
	long long pm/* 排名 */,bh/* 编号 */;
}stud[10002]; 
bool cmp(node x,node y){// 排序排名降序 
	if(x.sum!=y.sum)return x.sum>y.sum;// 判断总分
	else{// 如果总分相同 
		if(x.chinese+x.math!=y.chinese+y.math)return x.chinese+x.math>y.chinese+y.math;// 比较语文和数学两科的总分
		else{
			if(max(x.chinese,x.math)!=max(y.chinese,y.math))return max(x.chinese,x.math)>max(y.chinese,y.math);//比较语文和数学两科的最高分
			else{
				// 并列 
				return 0;// 可以 return 1 也可以 return 0 
			}
		}
	}
}
bool cmp1(node x,node y){// 按编号复原升序 
	return x.bh<y.bh;// 按编号复原 
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>stud[i].chinese>>stud[i].math>>stud[i].english,stud[i].sum=stud[i].chinese+stud[i].math+stud[i].english/* 输入并计算总和 */,stud[i].bh=i/* 赋值编号 */; 
	sort(stud+1,stud+1+n,cmp);// 排序排名
	int cnt=1;// 上一个人的排名 
	for(int i=1;i<=n;i++){
		if(stud[i].sum==stud[i-1].sum// 判断总分 
		&&stud[i].chinese+stud[i].math==stud[i-1].chinese+stud[i-1].math// 判断语文和数学两科的总分
		&&max(stud[i].chinese,stud[i].math)==max(stud[i-1].chinese,stud[i-1].math)){// 比较语文和数学两科的最高分
			stud[i].pm=cnt;// 如果都相同那么说明并列 
		}
		else{
			cnt=i;// 将名次赋值为 i 
			stud[i].pm=cnt;// 赋值排名 
		}
		//cout<<stud[i].bh<<" "<<stud[i].sum<<" "<<stud[i].chinese+stud[i].math<<" "<<stud[i].chinese<<" "<<stud[i].math<<"\n";
	}
	sort(stud+1,stud+1+n,cmp1);// 还原编号 
	for(int i=1;i<=n;i++)cout<<stud[i].pm<<"\n";// 输出排名 
	return 0;
}