PAT (Basic Level) Practice题解 1015 德才论 [C语言实现]

本博客详细介绍了PAT (Basic Level) 实践题1015 - 德才论的解题思路和C语言实现。首先将考生分为5类,依据分数和品德进行排序。在C语言中,使用qsort函数进行排序,确保在时间复杂度上满足要求。同时,提供了参考链接以供进一步学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

原题链接
在这里插入图片描述
在这里插入图片描述

思路

  • 基本思路

    • 先按分数分成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.自己写的改了很久,发现还是大佬的代码精简,感谢大佬,这里就整理了下,写了点中文备注

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值