题目
思路
-
基本思路
- 先按分数分成5类。
- ① 才德全尽
- ② 德胜才
- ③ “才德兼亡”但尚有“德胜才”者
- ④ 其余录取者
- ⑤ 被淘汰者
- 按总分排序
- 总分相同时,按德分排序
- 德分相同时,按学号先后排序
- 先按分数分成5类。
-
注意点:
这里需要用到C标准库的函数qsort,也就是快速排序,不然耗时通过不了
qsort函数学习笔记
快速排序数据结构算法
代码
#include <stdio.h>
#include <stdlib.h>
typedef struct _Student{
int ID; //学号
int D; //德分
int C; //才分
int rank; //分类排名
int sum; //总分=德分+才分
}sStudent, *Student;//声明结构体_Student可以用sStudent和指针Student来声明
//分类的函数
int rank(Student s, int H, int L)
{
if(s->D < L || s->C < L) return 0; // rank=0,说明未达到录取标准
else if(s->D >= H && s->C >= H) return 4; //德分和才分均不低于此线的被定义为“才德全尽”
else if(s->D >= H) return 3; //才分不到但德分到线的一类考生属于“德胜才”
else if(s->D >= s->C) return 2; //德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者
else return 1; //其他达到最低线L的考生
}
int comp(const void *a, const void *b)
{
Student s1 = *(Student*)a;
Student s2 = *(Student*)b;
if(s1->rank != s2->rank) return s1->rank - s2->rank;//按rank类别排序
else if(s1->sum != s2->sum) return s1->sum - s2->sum;//类别相同,则按总分排序
else if(s1->D != s2->D) return s1->D - s2->D;//总分相同,则按德分高低排序
else if(s1->ID != s2->ID) return s2->ID - s1->ID;//德分相同,则按学号ID顺序排序
else return 0;
}
int main()
{
int N, L, H, M = 0;
Student students[100000] = {0};
sStudent buffer[100000];//缓存区
scanf("%d %d %d", &N, &L, &H);//录入预设N、L、H
for(int i = 0; i < N; i++)
{
Student s = buffer + i;//指针位置+i,就是按顺序把数据录入缓存区(以Student结构体的大小分配单位空间)
scanf("%d %d %d", &s->ID, &s->D, &s->C);
s->sum = s->D + s->C;//算总分
if((s->rank = rank(s, H, L)) != 0) //返回值不为零,也就是将达到录取标准的数据记录下来
students[M++] = s;//将缓存区内的s赋值给students[M],然后M++
}
qsort(students, M, sizeof(Student), comp);//快速排序,注意:按照comp函数,这是升序排序
printf("%d\n", M);//输出录取人数
for(int i = M - 1; i >= 0; i--)//因此,从序号M-1开始倒着输出,就是从大到小排列
printf("%d %d %d\n", students[i]->ID, students[i]->D, students[i]->C);
return 0;
}
参考链接
代码出处
PS.自己写的改了很久,发现还是大佬的代码精简,感谢大佬,这里就整理了下,写了点中文备注