题意
第一行给出三个整数 N, L, H
表示 学生人数,最低录取分数线 和 优先录取线(其实就是优秀和良好的分界线啦)。
然后给出一大堆学生的 学号和其各自的 德才分。让你按司马光的理论给出录取排名。
总结一下排名次的要求如下:
- 德才分只要有一个没及格(即没达到最低录取分数线
L
)直接剔除,不放入排名。 - 排名先分类,后在各类别中按德才总分排序。
- 分类分四类:
第一类:“才德全尽”— 德,才两项分数均大于等于优先录取线H
。
第二类:“德胜才”— 德分大于等于优先录取分数线H
,但才分没达到。
第三类:“才德兼亡”但尚有“德胜才”— 德才分均未达到优先录取线H
,但德分不低于才分。
第四类:“才胜德”— 除上述三类之外的其他未不及格考生。 - 如果德才总分相同,则德分高排前;若仍相同,则按准考证号升序排列。
最后输出录取人数和排好名次的学生信息即可。
分析
既然排名次的要求写得这么明确,那我们就直接写一个cmp
,然后让sort()
直接帮我们排好序就好了。
注意好排序的要求,应该不会出错。
代码
#include <cstdio>
#include <algorithm>
using namespace std;
#define stuMAX 100005
struct stu{
int no;
int d, c; // 德, 才
};
stu s[stuMAX];
int N, L, H;
int level( stu a ){
if( a.d >= H ){
if( a.c >= H ) return 1;
else return 2;
}
else if( a.d >= a.c ) return 3;
return 4;
}
bool judge( stu a, stu b ){
if( a.d + a.c != b.d + b.c ) return a.d + a.c > b.d + b.c;
if( a.d != b.d ) return a.d > b.d;
return a.no < b.no;
}
bool cmp( stu a, stu b ){
int la = level( a );
int lb = level( b );
if( la != lb ) return la < lb;
return judge( a, b );
}
int main()
{
while( ~scanf( "%d%d%d", &N, &L, &H ) ){
for( int i = 0; i < N; i++ ){
scanf( "%d %d %d", &s[i].no, &s[i].d, &s[i].c );
if( s[i].d < L || s[i].c < L ){
i--;
N--;
}
}
sort( s, s + N, cmp );
printf( "%d\n", N );
for( int i = 0; i < N; i++ ){
printf( "%d %d %d\n", s[i].no, s[i].d, s[i].c );
}
}
return 0;
}
小结
一看我这么帅就是德才兼备,德才全尽啊!
请录取我!