gesp(C++五级)(7)洛谷:B3968:[GESP202403 五级] 成绩排序

gesp(C++五级)(7)洛谷:B3968:[GESP202403 五级] 成绩排序

gesp(C++五级)(7)洛谷:B3968:[GESP202403 五级] 成绩排序_第1张图片

题目描述

n n n 名同学,每名同学有语文、数学、英语三科成绩,你需要按照如下规则对所有同学的成绩从高到低排序:

  1. 比较总分,高者靠前;
  2. 如果总分相同,则比较语文和数学两科的总分,高者靠前;
  3. 如果仍相同,则比较语文和数学两科的最高分,高者靠前;
  4. 如果仍相同,则二人并列。

你需要输出每位同学的排名,如遇 x x x 人并列,则他们排名相同,并留空后面的 x − 1 x - 1 x1 个名次。例如,有 3 3 3 名同学并列第 1 1 1,则后一名同学自动成为第 4 4 4 名。

输入格式

第一行一个整数 N N N,表示同学的人数。
接下来 N N N 行,每行三个非负整数 c i , m i , e i c_i, m_i, e_i ci,mi,ei 分别表示该名同学的语文、数学、英语成绩。

输出格式

输出 N N N 行,按输入同学的顺序,输出他们的排名。
注意:请不要按排名输出同学的序号,而是按同学的顺序输出他们各自的排名。

样例 #1

样例输入 #1

6
140 140 150
140 149 140
148 141 140
141 148 140
145 145 139
0 0 0

样例输出 #1

1
3
4
4
2
6

提示

  • 30 % 30\% 30% 的数据, N ≤ 100 N \leq 100 N100,且所有同学总分各不相同。
  • 对全部的测试数据,保证 2 ≤ N ≤ 1 0 4 2 \leq N \leq 10^4 2N104 0 ≤ c i , m i , e i ≤ 150 0 \leq c_i, m_i, e_i \leq 150 0ci,mi,ei150

AC代码(100分)

#include
using namespace std;
/*思路:
   结构体排序
*/ 
int n; 
//结构体
struct node{
	int c,m,e;//语数英成绩
	int t;//总分 
	int id;//编号 
	int r;//排名 
}a[10010]; 
//排序规则函数1
bool cmp(node a,node b){
	if(a.t!=b.t) return a.t>b.t;
	else if((a.c+a.m)!=(b.c+b.m)) return (a.c+a.m)>(b.c+b.m);
	else if(max(a.c,a.m)!=max(b.c,b.m)) return max(a.c,a.m)>max(b.c,b.m);
	else return 1; 
} 
//排序规则函数2:按原编号重新排序 
bool cmp2(node a,node b){
	return a.id<b.id;
}
int main(){ 
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].c>>a[i].m>>a[i].e;
		a[i].t=a[i].c+a[i].m+a[i].e;//计算总分 
		a[i].id=i;//编号 
	}
	//排序
	sort(a+1,a+n+1,cmp);
	//排名
	for(int i=1;i<=n;i++){
		bool f = a[i].t==a[i-1].t && a[i].c+a[i].m==a[i-1].c+a[i-1].m && max(a[i].c,a[i].m)==max(a[i-1].c,a[i-1].m);
		if(f){
			a[i].r=a[i-1].r; //如果并列,当前的名次和上一个人的名次相同 
		}else{ 
			a[i].r=i;//如果不并列,按顺序往下排名 
		}
		 
	} 
	//输出结果要求的排序
	sort(a+1,a+n+1,cmp2);
	for(int i=1;i<=n;i++){
		cout<<a[i].r<<endl;
	} 
	return 0;
} 

文末彩蛋:

点击王老师青少年编程主页有更多精彩内容

你可能感兴趣的:(GESP(C++,四级+五级+六级)真题题解,c++,开发语言,算法,数据结构,csp,信奥赛,gesp)