PAT 乙级 1015 德才论 (25分)思路分析

宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”

现给出一批考生的德才分数,请根据司马光的理论给出录取排名。

输入格式:

输入第一行给出 3 个正整数,分别为:N(≤10
​5
​​ ),即考生总数;L(≥60),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线 L 的考生也按总分排序,但排在第三类考生之后。

随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分,其中准考证号为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。

输出格式:

输出第一行首先给出达到最低分数线的考生人数 M,随后 M 行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。

输入样例:

14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60

输出样例:

12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

代码思路:

这道题题目给的逻辑其实很简单,化简一下就是将考生按分数分为5类,按照题目要求第一类考生是德分和才分都不低于优先录取线,第二类考生是德分>H(优先录取线),但是才分<H;第三类考生则是德分才分都比优先录取线低,但是德分要不低于才分;其他高于最低录取线(L)的为第四类考生,在这里我将不到最低录取线的学生设置为第五类。方便后续排序;
然后这里的关键是结构体里要设置总分和等级。然后利用qsort函数按照要求进行排序;关于qsort函数大家如果不知道可以百度一下,其实也很好理解的 ,就是按照一定要求进行快速排序,比我们自己写要方便很多。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Student{
	int id;\\题目给出ID的要求是不超过8位的整数故直接用intint cf,df,zf;
	int lev;\\设置等级
}student;
int comp( const void *a,const void  *b){
	student *c=(student*)a;
	student *d=(student*)b;
	if(c->lev!=d->lev){
		return c->lev-d->lev;\\按照等级升序
	}else if(c->zf!=d->zf){
		return d->zf-c->zf;\\等级相同按照总分降序
	}else if(c->df!=d->df){
		return d->df-c->df;\\总分相同按照德分降序
	}else if(c->id!=d->id){
		return c->id-d->id;\\要是以上都相同则按照id降序
	}
	
}



int main(){
	int n,l,h;
	scanf("%d %d %d",&n,&l,&h);
	student s[n];
	int i;
	int count=n;\\开始假设及格人数为总人数;
	for(i=0;i<n;i++){
		scanf("%d %d %d",&s[i].id,&s[i].df,&s[i].cf);
		if(s[i].cf<l||s[i].df<l){
			s[i].lev=5;\\不及格人数设为第五类
			count--;
		}else if(s[i].df>=h&&s[i].cf>=h){
			s[i].lev=1;\\高于优先录取线设为第一类
			s[i].zf=s[i].cf+s[i].df;
		}else if(s[i].df>=h&&s[i].cf<h){
			s[i].lev=2;\\德分到线才分不到设为第二类
			s[i].zf=s[i].cf+s[i].df;
		}else if(s[i].df<h&&s[i].cf<h&&s[i].df>=s[i].cf){
			s[i].lev=3;\\德分和才分都不到线但是德分>=才分的设为第三类
			s[i].zf=s[i].cf+s[i].df;
		}else{\\剩下的就归为第四类;
			s[i].lev=4;
			s[i].zf=s[i].cf+s[i].df;
		}
	}
	printf("%d\n",count);
	qsort(s,n,sizeof(s[0]),comp);\\用qsort进行排序
	for(i=0;i<count;i++){\\从头输出就好了
		printf("%d %d %d\n",s[i].id,s[i].df,s[i].cf);
	}
	
}

题外话

我一开始是自己写排序算法按照这个题目要求进行排序,但是太麻烦了而且代码一长段看着就头疼,换成qsort瞬间神清气爽哈哈哈哈

发布了3 篇原创文章 · 获赞 1 · 访问量 21

猜你喜欢

转载自blog.csdn.net/cxyzzzzz/article/details/105025600