每日一题 成绩排名

今天来完成一题非常非常细节的题目,卡了我整整两天 看题目:

这个学期计算专业考了数据结构、计组、英语三门课,班长拿到了全班的成绩,想要对大家按照成绩进行排名(排名规则:平均分高的排名靠前,如果平均分一样数据结构成绩高的排名靠前,总分和数据结构成绩都一样的,计组成绩高的排名靠前,三门课成绩都相同的,保持原本的相对顺序),但是班长的电脑坏了,在排序的时候无法交换相邻的两个人,问在进行了多次交换之后(可能是0次)的排名。

输入格式:

每个测试包含多个测试用例。

第一行包含一个正整数T(1≤T≤10),表示测试用例的数量,测试用例的描述如下。

第二行包含一个正整数n(1≤n≤200000),表示班级的人数。

再下面n行每行包含一个字符串s(0<∣s∣<10)名字,保证每个人名字不相同,后面三个整数x,y,z(0<x,y,z≤100)对应数据结构、计组、英语的成绩。

输出格式:

每个测试样例输出n个字符串,对应每个人的名字,每个名字后面带一个空格,最后一行有换行

输入样例:

1
3
a 10 10 10
b 5 5 5
c 20 20 20

输出样例:

c b a 

样例解释:

a的平均成绩10,b的平均成绩5,c的平均成绩20,c比平均成绩高所以交换ac,排名变成c b aa的平均成绩比b高,但是a b相邻无法交换,最后答案是c b a

我们第一次看到这个题目肯定会觉得哦,相邻元素不能交换,那就交换的时候不判断左右元素,把不相邻的位置直接swap 比如 4 5 6 7 ->6 5 4 7->7 5 4 6->7 6 4 5 像这样 但其实并不是,题目说了左右不交换 但我们其实可以 4 5 6 7>>6  5 4 7>>7 5 4 6>> 7 6 4 5>> 5 6 4 7>>4 6 5 7>> 7 6 5 4    你会发现对4个以上的排序,这样的排序规则其实是没有影响的

所以我们可以总结出:

对于一个元素:不需要排序直接输出就可以看了

两个元素:相邻元素不需要排序直接输出就好

三个元素 只要比较第一个和第三个元素 第二个元素不用管他

第四个排序,直接用利用sort排序完成排序就可以

对于规则:

平均分高的排名靠前,如果平均分一样数据结构成绩高的排名靠前,总分和数据结构成绩都一样的,计组成绩高的排名靠前,三门课成绩都相同的,保持原本的相对顺序

那我们就需要一个结构体来记录这些分数:

typedef struct students
{
    string name;
    int a,b,c;
    double avg;
    int id;
}stu;

 因为他们再排序的过程中,如果平均分和三项成绩都一样,要保持原本的顺序所以我们需要一个id来记录我们读的时候的顺序 ,然后再开一个比较器cmp来进行所需规则的排序:

bool cmp(stu a,stu b){
	
	if(a.avg==b.avg) {
		if(a.a ==b.a) {
			if(a.b ==b.b){
				if(a.c==b.c) 
				return a.id<b.id;//在三项都相同的情况下保持id的排序 因为你读进来的时候是按升序,所以这里也是升序
			
			return a.c>b.c;
		}
		return a.b>b.b;
	}
	return a.a>b.a;
}
return a.avg>b.avg;
}

打印名字:

void print (vector<stu> &a){
		for(int k = 0;k<a.size();k++) {
				cout<<a[k].name<<" ";
					}
					cout<<endl;
}

这边要注意的就是再读入三个数据的时候的排序 要重新写一个:

else if(sum==3) {
		if(a[0].avg<a[2].avg) swap(a[0],a[2]);
		if(a[0].avg==a[2].avg) {
                if(a[0].a<a[2].a) swap(a[0],a[2]);
                else if(a[0].a==a[2].a) {
                    if(a[0].b<a[2].b) swap(a[0],a[2]);
                    else if(a[0].b ==a[2].b){
                         if(a[0].c<a[2].c) swap(a[0],a[2]);
                    }
                }
            }
        print(a);
	}

然后其他就没什么需要注意的了 常规读入输出调用就可以了

完整代码实现:

#include<bits/stdc++.h>
using namespace std;
typedef struct students
{
    string name;
    int a,b,c;
    double avg;
    int id;
}stu;

bool cmp(stu a,stu b){
	
	if(a.avg==b.avg) {
		if(a.a ==b.a) {
			if(a.b ==b.b){
				if(a.c==b.c) 
				return a.id<b.id;
			
			return a.c>b.c;
		}
		return a.b>b.b;
	}
	return a.a>b.a;
}
return a.avg>b.avg;
}
void print (vector<stu> &a){
		for(int k = 0;k<a.size();k++) {
				cout<<a[k].name<<" ";
					}
					cout<<endl;
}

int main()
{
    int n;
    cin>>n;
    vector<stu> a;
    stu temp;
    string name;
    int x,y,z,sum;
    double avg;
    for(int i = 0;i<n;i++){
    	cin>>sum;
    	for(int j = 0;j<sum;j++){
		cin>>name>>x>>y>>z;
		avg = (x+y+z)/3.0;
		temp.name = name;
		temp.a = x;temp.b = y;temp.c = z;temp.avg = avg;temp.id = j;
		a.push_back(temp);
	}
	if(sum<=2) print(a);
	else if(sum==3) {
		if(a[0].avg<a[2].avg) swap(a[0],a[2]);
		if(a[0].avg==a[2].avg) {
                if(a[0].a<a[2].a) swap(a[0],a[2]);
                else if(a[0].a==a[2].a) {
                    if(a[0].b<a[2].b) swap(a[0],a[2]);
                    else if(a[0].b ==a[2].b){
                         if(a[0].c<a[2].c) swap(a[0],a[2]);
                    }
                }
            }
        print(a);
	}


   else {
		sort(a.begin(),a.end(),cmp);
		print(a);
	}

	
	a.clear();
    }
}


提交结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值