简单解释题目的分类:题目中有四类学生,为了筛选的便捷,先把条件最严苛的挑选出来,前提是德和才都>L。
第一类:德和才>H。
第二类:德>=H,才<H,
第三类:德和才<H,德>才,
第四类:就是剩下的。关于类按总分排序,相同总分按照德分降序,以上都相同按准考证降序。
思路:首先要读取学生的德才分数,这里用vector动态数组作为容器。分类出来的学生也需要定义四个类。所以需要定义结构体将准考证号和德才封装到一起作为一个类(push_back)。之后考虑到输出排序的问题,属于多条件级联排序(总分相同时 → 德分相同时 → 准考证号)。
// 伪代码表示排序逻辑
if (总分不同) {
按总分降序排列
} else if (德分不同) {
按德分降序排列
} else {
按准考证号升序排列
} //(逻辑)
// 多条件排序的通用模式
if (第一条件不同) {
return 第一条件的比较结果;
} else if (第二条件不同) {
return 第二条件的比较结果;
} else {
return 第N条件的比较结果;
} //(对下面比较代码逻辑的解释)
auto cmp=[](const Student& a, const Student& b){
int sum_a=a.de+a.cai, sum_b=b.de + b.cai;
if(sum_a!=sum_b) return sum_a>sum_b;
else if(a.de!=b.de) return a.de>b.de;
else return a.id<b.id;
};
为什么return a>b?
---------------------------------------------------------------------------------------------------------------------------------
知识点:结构体用于定义自定义数据类型,将相关数据字段组合
相当于创建了一个新的"考生"数据类型
使代码更模块化、可读性更好、更易维护
#include<bits/stdc++.h>
using namespace std;
struct Student{
int id,de,cai;
};
int main()
{
int N,L,H;
cin>>N>>L>>H;
vector<Student> students(N);
for(int i=0;i<N;i++)
{
cin>>students[i].id>>students[i].de>>students[i].cai;
}
vector<Student> classes[4];
for(const auto& stu : students){
if(stu.de>=L &&stu.cai>=L)
{
if(stu.de>=H && stu.cai>=H) classes[0].push_back(stu);
else if(stu.de>=H &&stu.cai<H) classes[1].push_back(stu);
else if(stu.de>=stu.cai) classes[2].push_back(stu);
else classes[3].push_back(stu);
}
}
auto cmp=[](const Student& a, const Student& b){
int sum_a=a.de+a.cai, sum_b=b.de + b.cai;
if(sum_a!=sum_b) return sum_a>sum_b;
else if(a.de!=b.de) return a.de>b.de;
else return a.id<b.id;
};
for(auto& c: classes) sort(c.begin(),c.end(), cmp);
int M=0;
for(const auto& c:classes){
M+=c.size();
}
cout<<M<<endl;
for(const auto& c:classes){
for(const auto& stu : c){
printf("%d %d %d\n", stu.id,stu.de,stu.cai);
}
}
return 0;
}
对题目中几个auto进行解释:
for(auto& c: classes) sort(c.begin(),c.end(), cmp);这里的auto让编译器去识别一下c的类型,这里是vector<Student>&,&是使用引用的标志,防止拷贝整个vector。目的是要修改每个类别的vector(进行排序),所以需要用引用。
auto cmp=[](const Student& a, const Student& b){...};为什么用 auto:Lambda表达式的类型是编译器生成的匿名类型,我们无法直接写出这个类型名称,auto 让编译器自动推导这个复杂的类型。
总体来说的用处都一样。
auto cmp = [](const Student& a, const Student& b) {...};是lambda表达式,为什么要用?
目前的理解是lambda不用思考类型了
后续更新其他写法。