题意理解
题面传送门
形式化题意:要排序
n
n
n 名同学的语数英三科考试成绩。规则:
- 总分高者在前;
- 如总分相同,比较数学和语文分数之和,高者在前;
- 如仍相同,比较语文和数学两科的最高分,高者靠前;
- 如果仍相同,则二人并列。
如果 x x x 人并列,则他们的排名相同,且要留空后面 x − 1 x-1 x−1 个名次。 例如:有 3 3 3 个人并列第一,则下一个人自动成为第 4 4 4 名。且输出要按照输入顺序进行输出。
思路
再输入完成后,记录下每个学生的输入顺序后,进行快速排序,然后通过操作,得出排名,最后按照输入顺序输出排名。
代码实现
对于这种排序题,我们可以使用结构体快排来实现。
首先我们来写一个自定义类型
n
o
d
e
node
node,其中包含学生的三科成绩、总分、输入顺序、排名。
struct node{
int m;//math
int c;//Chinese
int e;//English
int num;//输入顺序
int ran;//排名
int tot;//total
};
然后输入学生人数 n n n,开一个数组 s t u stu stu,进行输入。并计算出总分和输入顺序。
cin>>n;
for(int i=0;i<n;i++){
cin>>stu[i].c>>stu[i].m>>stu[i].e;
stu[i].num=i;
stu[i].tot=(stu[i].c+stu[i].e+stu[i].m);
}
然后用 C++ 内置的
s
o
r
t
sort
sort 快排函数进行快排(这里不建议手写快排,因为在某些情况下,手写的快速排序可能会退为
O
(
n
2
)
O(n^2)
O(n2) 的时间复杂度,而
s
o
r
t
sort
sort 把时间复杂度压到了
O
(
n
log
n
)
O(n \log n)
O(nlogn))。但是,
s
o
r
t
sort
sort 在只有两个参数的情况下,是不能对自定义数据进行排序的,所以我们可以写一个
c
m
p
cmp
cmp 比较函数来实现这个功能。
c
m
p
cmp
cmp 的基本格式如下:
bool cmp(数据类型 x, 数据类型 y){
if(条件1){
return 结果1;
}else if(条件2){
return 结果2;
}else{//还可以写很多分支
return 条件n;
}
}
在这道题里,按照题面要求,应为这样:
bool cmp(node x,node y){
if(x.tot!=y.tot){
return x.tot>y.tot;
}else if((x.tot-x.e)!=(y.tot-y.e)){
return (x.tot-x.e)>(y.tot-y.e);
}else if(max(x.c,x.m)!=max(y.c,y.m)){
return max(x.c,x.m)>max(y.c,y.m);
}else{
return true;//也可以写 false
}
}
然后我们通过这种方式:sort(stu,stu+n,cmp)
,进行排序。
在排序结束后,我们通过判断前后两个元素是否完全相等(按照题面的排序要求进行判断)来实现名次的计算。判断全等的代码如下:
bool all_sqe(node a,node b){
if((a.tot==b.tot)&&((a.c+a.m)==(b.c+b.m))&&(max(a.c,a.m)==max(b.c,b.m))){
return true;
}else{
return false;
}
}
计算排名的代码如下:
for(int i=0;i<n;i++){
stu[i].ran=(i+1);//这里不能写 stu[i].ran=i,要不然会出现第零名
if(all_sqe(stu[i],stu[i-1])){
stu[i].ran=stu[i-1].ran;
}
}
最后通过一个双重 f o r for for 循环来用原来的输入顺序进行输出:
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(stu[j].num==i){
cout<<stu[j].ran<<endl;
}
}
}
然后 return 0;
就收工啦。
完整代码
#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
int m;
int c;
int e;
int num;
int ran;
int tot;
}stu[10005];
bool cmp(node x,node y){
if(x.tot!=y.tot){
return x.tot>y.tot;
}else if((x.tot-x.e)!=(y.tot-y.e)){
return (x.tot-x.e)>(y.tot-y.e);
}else if(max(x.c,x.m)!=max(y.c,y.m)){
return max(x.c,x.m)>max(y.c,y.m);
}else{
return true;
}
}
bool all_sqe(node a,node b){
if((a.tot==b.tot)&&((a.c+a.m)==(b.c+b.m))&&(max(a.c,a.m)==max(b.c,b.m))){
return true;
}else{
return false;
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>stu[i].c>>stu[i].m>>stu[i].e;
stu[i].num=i;
stu[i].tot=(stu[i].c+stu[i].e+stu[i].m);
}
sort(stu,stu+n,cmp);
for(int i=0;i<n;i++){
stu[i].ran=(i+1);
if(all_sqe(stu[i],stu[i-1])){
stu[i].ran=stu[i-1].ran;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(stu[j].num==i){
cout<<stu[j].ran<<endl;
}
}
}
return 0;
}