✅ PAT 乙级题目讲解1015《德才论》 摘要本文详细讲解了 PAT 乙级 1015《德才论》的解题思路与代码实现。题目以司马光的“德才论”为背景要求将考生按德分与才分划分为圣人、君子、小人、愚人四类并在各类内部按总分、德分、准考证号三级排序输出。文章涵盖了分类判断、自定义排序函数、完整 C 代码、常见错误提醒及复杂度分析适合作为结构体排序与多条件比较的模板练习。 题目简介本题考查结构体排序与多条件比较是一道典型的“模拟自定义排序”问题。题目源自宋代司马光提出的“德才论”要求我们依据德分和才分将考生分类排序。考生被分为以下四类才德全尽圣人德分和才分均不小于优先线H;德胜才君子德分 ≥H才分 H;才德兼亡但德胜才小人德分 H且才分 H但德分 ≥ 才分;其余及格者愚人: 其余德分 ≥L才分 ≥L排序优先级​ 总分从高到低 → 德分从高到低 → 准考证号从小到大。(三级嵌套) 样例分析样例输入14 60 80 10000001 64 90 10000002 90 60 ...总共 14 个学生最低线L为 60优先线H为 80。遍历每个考生后满足德才 ≥ 60 的为合格考生 计数人数m再按分数划分四类分别加入对应数组每类内部排序后依次输出所有人。输出12 10000013 90 99 10000012 80 100 ... 解题思路本题关键是考生分类 多维排序理解四类考生分类标准如下。类别条件优先级第 1 类才德全尽德分 ≥ H 且 才分 ≥ H最高第 2 类德胜才德分 ≥ H 且 才分 H第二第 3 类德才兼亡但德胜才德分 H 且 才分 H 且 德分 ≥ 才分第三第 4 类普通达线德才 ≥ L 但不满足前几类最低 变量说明变量名含义n考生总数l录取最低分数线h优先录取分数线m合格考生总数id准考证号d德分c才分s总分a1 ~ a4四类考生数组c1 ~ c4每类考生人数计数器t临时学生对象✅ Step 1定义结构体并读入数据structStu{intid,d,c,s;}a1[maxn],a2[maxn],a3[maxn],a4[maxn],t;读取n个考生数据并判断是否达到最低线if(t.dlt.cl){m;// 分类进入 a1~a4}✅ Step 2对每位考生判断分类分组保存我们需将所有达线德分和才分均 ≥ L的考生按照上述条件放入不同数组 a1 ~ a4。if(t.dht.ch)→ 存入 a1c1 记录人数elseif(t.dht.ch)→ 存入 a2c2 记录人数elseif(t.dt.c)→ 存入 a3c3 记录人数else→ 存入 a4c4 记录人数✅ Step 3排序规则设计每一类内部的排序规则相同按以下顺序德才总分降序若总分相同德分高者优先若德分也相同准考证号小者优先。可以使用自定义排序函数处理比较规则函数cmp定义如下。boolcmp(Stu x,Stu y){if(x.sy.s){// 若总分相同if(x.dy.d)// 若德分也相同returnx.idy.id;// 准考证号小者优先returnx.dy.d;// 德分高者优先}returnx.sy.s;// 德才总分降序}✅ Step 4合并所有类别结果并输出四类考生分别排序后依次合并输出最终排序结果。sort(a11,a1c11,cmp);sort(a21,a2c21,cmp);sort(a31,a3c31,cmp);sort(a41,a4c41,cmp);printf(%d\n,m);...✅ 完整代码#includebits/stdc.husingnamespacestd;constintmaxn1e55;intn,l,h,m,c1,c2,c3,c4;structStu{intid,d,c,s;}a1[maxn],a2[maxn],a3[maxn],a4[maxn],t;boolcmp(Stu x,Stu y){if(x.sy.s){// 若总分相同if(x.dy.d)// 若德分也相同returnx.idy.id;// 准考证号小者优先returnx.dy.d;// 德分高者优先}returnx.sy.s;// 德才总分降序}intmain(){scanf(%d %d %d,n,l,h);for(inti1;in;i){scanf(%d %d %d,t.id,t.d,t.c);t.st.dt.c;if(t.dlt.cl){m;if(t.dht.ch){a1[c1]t;}elseif(t.cht.dh){a2[c2]t;}elseif(t.dt.c){a3[c3]t;}else{a4[c4]t;}}}sort(a11,a1c11,cmp);sort(a21,a2c21,cmp);sort(a31,a3c31,cmp);sort(a41,a4c41,cmp);printf(%d\n,m);for(inti1;ic1;i){printf(%d %d %d\n,a1[i].id,a1[i].d,a1[i].c);}for(inti1;ic2;i){printf(%d %d %d\n,a2[i].id,a2[i].d,a2[i].c);}for(inti1;ic3;i){printf(%d %d %d\n,a3[i].id,a3[i].d,a3[i].c);}for(inti1;ic4;i){printf(%d %d %d,a4[i].id,a4[i].d,a4[i].c);if(ic4)printf(\n);}return0;} 常见错误提醒错误点原因说明分类判断顺序写错顺序错误会导致学生进错组sort 比较函数条件遗漏总分、德分、ID 三重判断缺一不可最后一类输出多余换行特判最后一位避免尾部多输出✅ 总结归纳本题是多维排序 多组存储的经典模拟题分类优先级需与题意严格一致排序需覆盖三重维度总分 德分 准考证号四类考生独立排序后统一输出时间复杂度读入与分类O(n)O(n)O(n)排序O(nlog⁡n)O(n \log n)O(nlogn)最多四次排序sort 内部实现是快排输出O(n)O(n)O(n)总体O(nlog⁡n)O(n \log n)O(nlogn)空间复杂度O(n)O(n)O(n)数组存储所有合格考生数据; 思维拓展本题分类排序思想可迁移至成绩评比、赛事排名、资源调度等问题若数据量更大需考虑使用堆或归并优化排序部分若考生分类进一步增加可考虑用 vector 数组结构替代四个静态数组。