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

· · 题解

结构体排序 + 模拟,建议评橙。

题目大意

给你 n 个学生的成绩,让你按输入循序输出每个学生的排名。

具体思路

读入的时候记录总分和顺序,再按照题目中给的方法进行结构体排序,(即总分不相等,把总分高的往前排;如果总分相等,数学和语文两科总分高的往前排;如果数学和语文两科总分也相等,数学和语文两科最高分高的靠前;如果数学和语文两科最高分也一样,就算并列),然后处理排名,如果排好后的第 i 个人和第 i-1 个人并列,那么第 i 个人的排名和第 i-1 个人一样;如果不并列,那么第 i 个人的排名就是 i

完整代码

废话不多说,上代码。

#include<bits/stdc++.h>
using namespace std;
struct student{
    int a/*语文成绩*/,b/*数学成绩*/,c/*英语成绩*/,s/*总分*/,id/*读入顺序*/,ans/*最终答案,即排名*/;
}a[10005];//数组开到1e4+5。 
bool cmp(student x,student y){//一号比较函数 。 
    if(x.s!=y.s)return x.s>y.s;//总分不一样按总分排。 
    if(x.a+x.b!=y.a+y.b)return x.a+x.b>y.a+y.b;//总分一样并且语文数学两科总分不一样,按语文数学两科总分排。 
    return max(x.a,x.b)>max(y.a,y.b);//总分以及语文数学两科的总分都一样,按语文数学两科最高分排,一样也没关系,之后会处理。 
}
bool cmp2(student x,student y){//二号比较函数。 
    return x.id<y.id;//按读入顺序从小到大排。 
}
int main(){//主函数。 
    int n;//n个学生。 
    cin>>n;//读入n。 
    for(int i=1;i<=n;i++){
        cin>>a[i].a>>a[i].b>>a[i].c;//读入三科成绩。 
        a[i].s=a[i].a+a[i].b+a[i].c;//记录总分。 
        a[i].id=i;//记录读入顺序。 
    }
    sort(a+1,a+n+1,cmp);//第一次排序。 
    for(int i=1;i<=n;i++){
        if(a[i].s==a[i-1].s && a[i].a+a[i].b==a[i-1].a+a[i-1].b && max(a[i].a,a[i].b)==max(a[i-1].a,a[i-1].b))//如果所有条件相同,即和前一个人并列。 
            a[i].ans=a[i-1].ans;//两人排名也相同。 
        else//和前一个人不并列。 
            a[i].ans=i;//排名就是i。 
    }
    sort(a+1,a+n+1,cmp2);//第二次排序。 
    for(int i=1;i<=n;i++)cout<<a[i].ans<<endl;//输出排名并换行。 
    return 0;
}