B3968 [GESP202403 五级] 成绩排序
B3968 [GESP202403 五级] 成绩排序
考察知识点:结构体排序
文章目录
- B3968 [GESP202403 五级] 成绩排序
- 题意
- 思路
- 数据约束
- 参考代码
- 常见错误

题意
根据要求排序,存在并列情况则名次一致
思路
先根据总成绩排序,然后如果相等则根据语数和排序,如果还相等则根据语数最值排序,都相等则并列
- 因此直接考虑结构体排序,根据对应数值来排即可
- 如何排?
先看数据发范围,因为是1e4的范围,如果直接普通的插入排序、冒泡排序、选择排序,O(n*n)有可能超时的风险
直接考虑结构体的快排,不会超时
- 如何根据原顺序输出排序后的位置?
旧位置→新位置,最简单的就是建立映射,设一个数组,下标储存结构体的初始位置,值存排序后的位置,最后输出数组即可
数据约束
注意n的范围设置结构体大小就行
参考代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
struct stu{int ch;int math;int en;int sum;//求总和int sum1;//求语数和int mn;//求最值 int k;//原始序号
}a[N];
bool f[N];//储存是否有重复
int a_index[N];
bool cmp(stu c1,stu c2){if(c1.sum == c2.sum){ //总分一致 if(c1.sum1 == c2.sum1){ //语数总分 if(c1.mn ==c2.mn){//最值也相等 return 0; // 并列 不影响 ,有返回值就行 }else{return c1.mn>c2.mn;}}else{ return c1.sum1>c2.sum1 ;}}else return c1.sum>c2.sum;
}
int main(){int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i].ch>>a[i].math>>a[i].en;a[i].sum = a[i].ch+a[i].math+a[i].en;a[i].sum1 = a[i].ch+a[i].math;a[i].mn = max(a[i].ch,a[i].math) ;a[i].k = i;} sort(a+1,a+n+1,cmp);//排序//处理并列数据for(int i=2;i<=n;i++){if((a[i].sum ==a[i-1].sum)&&(a[i].sum1 ==a[i-1].sum1)&&(a[i].mn ==a[i-1].mn)) {f[i]= 1;//是当前位置标记为并列位置 }}for(int i=1;i<=n;i++){if(!f[i]) a_index[a[i].k] = i;//排序前的位置和排序后的位置建立一一对应关系 else{ //处理并列关系 a_index[a[i].k] = a_index[a[i-1].k];}}for(int i=1;i<=n;i++){cout<<a_index[i]<<" "<<endl; }return 0;
}
常见错误
- sort(a,b,c)参数问题, 前面两个参数对应数组的begin和end的迭代器(理解为地址),是左闭右开的空间(end是最后一个元素的后一个位置)
- 使用index作为数组/变量名字,由于和库函数中名字重复,会报错,因此避免使用index、count、list等常见库函数名作为变量名,推荐命名规范:pos_map、original_index等具名变量