#include <bits/stdc++.h>
using namespace std;
struct Student{
int id, de, cai, sum, level;
// 重载 内部排序
bool operator < (Student s) const{
// 分类从高到低排序
if(level != s.level)
return level < s.level;
// 总分相同时德分降序
else if(sum != s.sum)
return sum > s.sum;
// 德分并列准考证号的升序输出
else if(de != s.de)
return de > s.de;
return id < s.id;
}
};
int main() {
int n, l, h, id, de, cai;
set<Student>stu;
cin >> n >> l >> h;
while(n--){
cin >> id >> de >> cai;
// 不及格直接跳过
if(de < l || cai < l)
continue;
// 一类 均不低于H
else if(de >= h && cai >= h)
stu.insert({id, de, cai, de + cai, 1});
// 二类 德>H L<才<H
else if(de >= h)
stu.insert({id, de, cai, de + cai, 2});
// 三类 L<均<H 才<德
else if(de >= cai)
stu.insert({id, de, cai, de + cai, 3});
// 四类 L<均<H 德<才
else
stu.insert({id, de, cai, de + cai, 4});
}
// 通过考生数
cout << stu.size() << endl;
for(auto s : stu)
cout << s.id << " " << s.de << " " << s.cai << endl;
}
bool operator < (Student s) const{
// 分类从高到低排序
if(level != s.level)
return level < s.level;
// 总分相同时德分降序
if(sum != s.sum)
return sum > s.sum;
// 德分并列准考证号的升序输出
if(de != s.de)
return de > s.de;
return id < s.id;
}
考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。
判断时候的 != 不等于,意味着不同分类的时候会进行升序或降序。而如果 == 相等 即意味某个特征是同一类,就需要遍历后面的判断,用其他的方式来决定对象的前后位置。
重载之后的内部排序,判断用 if 或 else if 都是可以的,因为会找到其中一个条件,直到满足就 return ,所以不管是多次判断的 if 还是,平行的只判断执行一次的 else if 最终都指向其中一个 return 就结束了。
int id, de, cai, sum, level;
因为这里的数据都是合法的所以可以全部设置为整型iint,比如准考证号首位是从1开始的,所以就可以用 int 来存储。而1025 反转链表,因为地址首位存在 0 ,从数字来说就不合法了,所以只能用 string 来存储。
else if (DS >= H && CS >= H)
else if (DS >= CS)
题目出现了”不低于“字眼,比如”德分和才分均不低于此线“,”德分不低于才分的考生“。在分类的时候要记得加上等号 = 。
de >= h && l <= cai < h
de >= h
原本二类排序写多一个判断,德>H && L<才<H。看参考代码里面可以简化后面才分的判断。因为一类判断的时候,判断一次,而二类判断的时候,如果满足 德>H 却又不是 才>H 那么才就必然有 才<H了。
同时前面有 if(de < l || cai < l) 的判断,如果任一不打到 L 线的就被略去了。所以才必然满足 L<才<H,所以省略就可以明白了。后面 de >= cai 也是同样的道理。
s.de, s,de
刚才编译器里把成员符号 . 达成了逗号 , 因为原本编译器里面的字体这两个差别不大,找了老半天才发现这两个的差别。所以后面把字体换成其他的,就好区分多了。
这题随机数据又有超时的可能,随机完全AC。