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

封面

思路:

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

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

代码:

// 以下代码与思路完全相同 
// 本代码已经提交测试并且已经 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;
}