宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”
现给出一批考生的德才分数,请根据司马光的理论给出录取排名。
输入第一行给出 3 个正整数,分别为:N(≤),即考生总数;L(≥),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线 L 的考生也按总分排序,但排在第三类考生之后。
随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分
,其中准考证号
为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。
输出第一行首先给出达到最低分数线的考生人数 M,随后 M 行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。
思路:
该题明显考察排序,首先有一个大方向,先构造一个学生的结构体数组(这类题的通解)。准考证号用字符数组方便输入输出,除了德分和才分还需要一个sum总分和这个学生的类别flag。
1 struct student{ 2 char num[10]; 3 int d,c,sum,flag;//flag用来标记类别 4 }stu[maxn];
主函数读入数据,读入数据以后直接用sort函数排序即可,那这题实际上是怎样构造sort函数里的cmp函数的问题。
首先想到,要按类别排序,故在读入数据时就进行类别(flag)的划分,接着注意到,无论是哪一类,都是按总分排序,总分相同排德分,德分相同排准考证号,那cmp函数就写完了。
注意准考证号是一个字符串,要用strcmp函数。
1 bool cmp(student a,student b){ 2 if(a.flag!=b.flag) return a.flag<b.flag;//类别不同时,类别增序排列 3 else if(a.sum!=b.sum) return a.sum>b.sum;//类别相同时,总分排序 4 else if(a.d!=b.d) return a.d>b.d;//总分相同时,德分排序 5 else return strcmp(a.num,b.num)<0;//德分相同时,准考证号排序 6 }
注意主函数里用来判断类别的if else语句,情况要考虑全。
完整代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=100010; 4 5 struct student{ 6 char num[10]; 7 int d,c,sum,flag;//flag用来标记类别 8 }stu[maxn]; 9 10 bool cmp(student a,student b){ 11 if(a.flag!=b.flag) return a.flag<b.flag;//类别不同时,类别增序排列 12 else if(a.sum!=b.sum) return a.sum>b.sum;//类别相同时,总分排序 13 else if(a.d!=b.d) return a.d>b.d;//总分相同时,德分排序 14 else return strcmp(a.num,b.num)<0;//德分相同时,准考证号排序 15 } 16 17 int main(){ 18 int n,l,h; 19 int m=0; 20 scanf("%d%d%d",&n,&l,&h); 21 for(int i=0;i<n;i++){ 22 scanf("%s%d%d",stu[i].num,&stu[i].d,&stu[i].c); 23 stu[i].sum=stu[i].d+stu[i].c; 24 if(stu[i].d<l||stu[i].c<l) { 25 stu[i].flag=5; 26 m++; 27 } 28 else if(stu[i].d>=h&&stu[i].c>=h) stu[i].flag=1; 29 else if(stu[i].d>=h&&stu[i].c<=h) stu[i].flag=2; 30 else if(stu[i].d>=stu[i].c) stu[i].flag=3; 31 else stu[i].flag=4; 32 } 33 m=n-m; 34 sort(stu,stu+n,cmp); 35 printf("%d\n",m); 36 for(int i=0;i<m;i++){ 37 printf("%s %d %d\n",stu[i].num,stu[i].d,stu[i].c); 38 } 39 }
原文:https://www.cnblogs.com/taiga/p/12616762.html