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

· · 题解

题意

给你几个规则,让你排序,然后进行输出。

分析

我们可以用结构体或者类 score 来存。接下来重载运算符即可。

第一个规则,比较总分。

(x.a+x.b+x.c)<(this->a+this->b+this->c))

第二个规则:总分相同比前两科。

((x.a+x.b+x.c)==(this->a+this->b+this->c)&&(x.a+x.b)<(this->a+this->b))

第三个规则:前两个规则都相同比前两科最大值。

(x.a+x.b+x.c)==(this->a+this->b+this->c)&&(x.a+x.b)==(this->a+this->b)&&max(x.a,x.b)<max(this->a,this->b)

连起来就是这样(我个人写重载运算符的码风不好,见谅)

bool operator < (const score x)const{
    return ((x.a+x.b+x.c)<(this->a+this->b+this->c))||((x.a+x.b+x.c)==(this->a+this->b+this->c)&&(x.a+x.b)<(this->a+this->b))||((x.a+x.b+x.c)==(this->a+this->b+this->c)&&(x.a+x.b)==(this->a+this->b)&&max(x.a,x.b)<max(this->a,this->b));
}

从这里开始,先排一遍序,为规则四做准备。

第四个规则:前三个规则都一样的时候那排名相同。

前三个规则都比较好做,那么第四个规则怎么办呢?

我们可以用二分。假如存下来的结构体数组名称为 a ,那我们就需要找 a 中大于等于 a[i] 的数。如果找到大于等于 a[i] 的数,就说明符合规则四,输出就行了(主要是奔着这个等于去找的,因为大于在排序里已经排过了)。

但是我们不能在 a 中找符合条件的 a[i] 。那我们可以再搞个 b ,把 b 赋值为 a ,在 a 中找 b[i]

接下来找到后输出就行了。

代码:

//step1:存结构体+重载
#include<bits/stdc++.h>
using namespace std;
const int N=114514;
struct score{
    int a,b,c;
    bool operator < (const score x)const{
        return ((x.a+x.b+x.c)<(this->a+this->b+this->c))||((x.a+x.b+x.c)==(this->a+this->b+this->c)&&(x.a+x.b)<(this->a+this->b))||((x.a+x.b+x.c)==(this->a+this->b+this->c)&&(x.a+x.b)==(this->a+this->b)&&max(x.a,x.b)<max(this->a,this->b));
    }
}a[N],b[N];
//如果你用的是类,那么这样写:
/*
class score{
    public:
        int a,b,c;
        bool operator < (const score x)const{
            return ((x.a+x.b+x.c)<(this->a+this->b+this->c))||((x.a+x.b+x.c)==(this->a+this->b+this->c)&&(x.a+x.b)<(this->a+this->b))||((x.a+x.b+x.c)==(this->a+this->b+this->c)&&(x.a+x.b)==(this->a+this->b)&&max(x.a,x.b)<max(this->a,this->b));
        }
}a[N],b[N];
*/
//step2:读入
signed main(){
    int n;cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i].a>>a[i].b>>a[i].c;
        b[i]=a[i];//把b赋值给a
    }
    //step3:排序
    sort(a+1,a+n+1);
//  step4:二分+输出
    for(int i=1;i<=n;i++){
        cout<<lower_bound(a+1,a+n+1,b[i])-a<<endl;//b中找a
    }
    return 0;
}