【Java】PAT(Basic Level) Practice(中文) 1015德才论

前言

※  PTA是 程序设计类实验辅助教学平台 ,里边包含一些编程题目集以供练习。

这道题用java解一定会超时,在文章结语部分我会证明。我用java试了四种解法,不断优化,但始终是三个测试点通过、三个测试点超时。我把我的代码放在这里,做个参考吧。文章最后附有C语言解法。


1015 德才论 题目

    题目    

作者 CHEN, Li

单位 浙江大学

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

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

输入格式:

输入第一行给出 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

 


Java代码    

我用java写了四种解法,测试结果都是三个测试点正确、三个测试点超时。研究半天也没搞明白到底为什么超时,大概是Java本身的速度不足吧。代码就发出来做个参考吧。

解法一  

首先,用二维数组存储所有学生信息,每个一维数组存储一个学生的信息。我用这个数组作为静态链表来排序(定义一个int作为头指针),每个学生的信息后都有一个int值指向排序下一名的学生的角标。最后打印时降序输出即可。要注意处理链表第一名的特殊情况,以及学生排序的逻辑。代码如下。

测试结果:三个测试点正确,另外三个测试点超时。

/*
功能:根据规则对给定考生成绩进行排序并输出
实现思路:用数组存储每个考生的信息,并且用数组作为静态链表实现排序。
时间复杂度   空间复杂度
*/
import java.io.*;
class Main{public static void main(String[] args) throws IOException{//接收输入BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] arr1 = br.readLine().split(" +");int n = Integer.parseInt(arr1[0]);    //考生总数int l = Integer.parseInt(arr1[1]);    //最低录取分数线int h = Integer.parseInt(arr1[2]);    //优秀录取线//在线排序int[][] a = new int[n][6];    //数组每一行代表一个考生,存储考号、德分、才分、总分、等级、链表序号int m = 0;            //录取总人数String[] b = new String[3];    //接收当前考生的信息int yi = -1;            //已录取学生排序链表中的第一名的角标for(int i=0;i<n;i++){        //在线处理每个考生的信息b = br.readLine().split(" +");    //接收当前考生的信息a[i][0] = Integer.parseInt(b[0]);        //将考生信息转为inta[i][1] = Integer.parseInt(b[1]);a[i][2] = Integer.parseInt(b[2]);a[i] = getGrade(a[i],l,h);    //调用函数填写总分及等级信息,排序地址初始化if(a[i][4]<5){                //若是第一~第四类考生m++;                        //则录取a = getSort(a,i,yi);           //调用函数填写链表地址信息if(a[i][5]==yi)            //判断是否要更新第一名的角标yi = i;}}//打印输出System.out.print(m);    //输出录取总人数if(m==0)    return;        //若是录取人数为0,则直接返回String stu = "";for(int i=yi;;i=a[i][5]){    //按数组静态链表的排序,以成绩降序输出stu = "\n" + a[i][0] + " " +a[i][1] + " " + a[i][2];System.out.print(stu);if(a[i][5]==-1)    //若是链表中录取的最后一名break;            //则跳出循环,停止打印}}private static int[] getGrade(int[] a,int l,int h){//功能:根据数组中学生成绩,填写总分及等级信息 。l是录取线,h是优秀线。a[3] = a[1] + a[2];    //计算总分a[5] = -1;             //排序地址信息初始化if(a[1]<l || a[2]<l){    //若德才有一项未达到录取线a[4] = 5;        //第五类考生,不予录取return a;}if(a[1]>=h && a[2]>=h){    //若德才均优秀a[4] = 1;        //第一类考生return a;}if(a[1]>=h){        //若德分优秀而才分不优秀a[4] = 2;        //第二类考生return a;}    if(a[1]>=a[2]){    //若德分不优秀,但德分≥才分a[4] = 3;        //第三类考生return a;}a[4] = 4;            //其它考生为第四类考生return a;}private static int[][] getSort(int[][] a,int t,int yi){//功能:对数组中指定学生的成绩(以数组静态链表方式)排序并返回数组//参数 a[][] 学生信息数组 ;t 待排序学生角标 ;yi 已排序的录取学生链表中第一名学生角标if(yi==-1)                    //如果链表中还没有学生return a;                   //则以待排序学生作为第一名,直接返回if(gradeCompare(a[t],a[yi])){        //如果待排序的学生是新的第一名a[t][5] = yi;                //待排序学生链接指向原先的第一名return a;}for(int i=yi,j=i;;i=a[i][5]){      //若链表中已经有至少一名学生,则正常进行排序if(gradeCompare(a[i],a[t])){    //若待排序学生成绩<当前对比学生成绩j=i;                            //用j记住当前对比学生角标if(a[i][5]==-1){                //若当前对比学生已经是最后一名a[i][5] = t;                    //将待排序学生插入到链表结尾break;                          //排序完毕,退出循环}}else{                          //若待排序学生成绩>当前对比学生成绩a[j][5] = t;                    //上一名的学生链接到待排序学生a[t][5] = i;                    //待排序学生链接到当前对比学生break;                            //排序完毕,退出循环}}  return a;}private static boolean gradeCompare(int[] a,int[] b){//功能:比较两个学生成绩,学生a是否排名比学生b更靠前if(a[4]<b[4])      //若a比b等级更高return true;if(a[4]>b[4])      //若a比b等级更低return false;//若ab等级相同if(a[3]>b[3])      //若总分a>breturn true;if(a[3]<b[3])      //若总分a<breturn false;//若ab总分相同if(a[1]>b[1])      //若德分a>breturn true;if(a[1]<b[1])      //若德分a<breturn false;//若ab德分相等   return (a[0]<b[0])?true:false;    //则按考号升序排序}
}


解法二 

考虑到解法一之所以超时,有可能是我自己写的排序算法太慢导致的,于是我就又写了一个算法,利用java自带的Comparator比较器来实现排序。主要思路是,在接收学生信息时只存储不排序,全部接收完毕后,调用java的排序算法,在Arrays.sort()函数中传入一个Comparator匿名内部类(以便自定义排序规则)作为参数,实现排序。最后再降序打印输出。

这个解法的一个缺点是要对包括未录取考生在内的所有考生进行排序,而解法一只对录取考生排序。(后续的解法我优化了这一点。)解法二的测试结果仍然是有三个测试点超时。代码如下。

/*
功能:根据规则对给定考生成绩进行排序并输出
实现思路:用数组存储每个考生的信息,并在Arrays.sort()中传入一个Comparator匿名内部类作为参数,以实现排序。
时间复杂度   空间复杂度
*/
import java.io.*;
import java.util.*;
class Main{public static void main(String[] args) throws IOException{//接收输入BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] arr1 = br.readLine().split(" +");int n = Integer.parseInt(arr1[0]);    //考生总数int l = Integer.parseInt(arr1[1]);    //最低录取分数线int h = Integer.parseInt(arr1[2]);    //优秀录取线//逐个接收考生信息Integer[][] a = new Integer[n][5];    //数组每一行代表一个考生,存储考号、德分、才分、总分、等级int m = 0;            //录取总人数String[] b = new String[3];    //接收当前考生的信息for(int i=0;i<n;i++){        //在线处理每个考生的信息b = br.readLine().split(" +");    //接收当前考生的信息for(int j=0;j<3;j++)a[i][j] = Integer.parseInt(b[j]);        //将考生信息转为int    a[i] = getGrade2(a[i],l,h);    //调用函数填写总分及等级信息if(a[i][4]<5){                //若是第一~第四类考生m++;                        //则录取}}//打印输出System.out.print(m);    //输出录取总人数if(m==0)    return;        //若是录取人数为0,则直接返回//调用java提供的数组排序Arrays.sort(a, new Comparator<Integer[]>() {    //new一个Comparator匿名内部类,重写compare方法public int compare(Integer[] b, Integer[] a) {if(a[4]<b[4])      //若a比b等级更高return 1;if(a[4]>b[4])      //若a比b等级更低return -1;//若ab等级相同if(a[3]>b[3])      //若总分a>breturn 1;if(a[3]<b[3])      //若总分a<breturn -1;//若ab总分相同if(a[1]>b[1])      //若德分a>breturn 1;if(a[1]<b[1])      //若德分a<breturn -1;//若ab德分相等   return (a[0]<b[0])?1:-1;    //则按考号升序排序}});//降序输出学生信息String stu = "";for(int i=0;i<m;i++){stu = "\n" + a[i][0] + " " +a[i][1] + " " + a[i][2];System.out.print(stu);}             }private static Integer[] getGrade2(Integer[] a,int l,int h){//功能:根据数组中学生成绩,填写总分及等级信息 。l是录取线,h是优秀线。a[3] = a[1] + a[2];    //计算总分if(a[1]<l || a[2]<l){    //若德才有一项未达到录取线a[4] = 5;        //第五类考生,不予录取return a;}if(a[1]>=h && a[2]>=h){    //若德才均优秀a[4] = 1;        //第一类考生return a;}if(a[1]>=h){        //若德分优秀而才分不优秀a[4] = 2;        //第二类考生return a;}    if(a[1]>=a[2]){    //若德分不优秀,但德分≥才分a[4] = 3;        //第三类考生return a;}a[4] = 4;            //其它考生为第四类考生return a;}
}    

解法三 

既然用java自带的排序算法也不行,那索性还是回到解法一的思路,自己用数组做静态链表的排序吧。考虑到解法一中每个考生排序都要从第一类第一名开始比较,比较耗时,因此我又改进了一下,给四个类别分别设置一个本类别第一名的int角标作为指针。这样,每个考生先计算类别并填写在数组中,在排序时只需从所属类别的第一名开始比较即可。此外,这个解法中我还把一些工具函数优化了一下。遗憾的是,测试结果仍然是三个点通过、三个点超时。

/*
功能:根据规则对给定考生成绩进行排序并输出
实现思路:用数组存储每个考生的信息,并且用数组作为静态链表实现排序。
时间复杂度   空间复杂度
*/
import java.io.*;
class Main{public static void main(String[] args) throws IOException{//接收基本信息输入BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] arr1 = br.readLine().split(" +");int n = Integer.parseInt(arr1[0]);    //考生总数int l = Integer.parseInt(arr1[1]);    //最低录取分数线int h = Integer.parseInt(arr1[2]);    //优秀录取线//数组初始化int[][] a = new int[n][6];    //数组每一行代表一个考生,存储考号、德分、才分、总分、等级、链表序号int m = 0;            //录取总人数String[] b = new String[3];    //接收当前考生的信息Integer yi[] = new Integer[4];  //已录取学生排序链表中第一类至第四类的第一名的角标for(int i=0;i<4;i++){           //数组初始化为-1yi[i] = -1;}//在线处理 接收每个学生信息并排序存入数组中for(int i=0,temp=-1;i<n;i++){        //在线处理每个考生的信息b = br.readLine().split(" +");    //接收当前考生的信息a[i][0] = Integer.parseInt(b[0]);        //将考生信息转为inta[i][1] = Integer.parseInt(b[1]);a[i][2] = Integer.parseInt(b[2]);a[i] = getGrade(a[i],l,h);    //调用函数填写总分及等级信息,排序地址初始化if(a[i][4]!=5){                //若是第一~第四类考生m++;                        //则录取temp =a[i][4]-1;     //当前学生所属类别,从0开始计数,yi[temp]是所属类别第一名的角标a = getSort(a,i,yi[temp]);           //调用函数填写链表地址信息if(a[i][5]==yi[temp])            //判断是否要更新该生所属类别第一名的角标yi[temp] = i;}}//打印输出System.out.print(m);    //输出录取总人数if(m==0)    return;        //若是录取人数为0,则直接返回String stu = "";for(int j=0;j<4;j++){       //遍历四个学生类别if(yi[j]==-1)               //若当前类别没有学生continue;               //就继续下一个类别for(int i=yi[j];;i=a[i][5]){    //按数组静态链表的排序,以成绩降序输出stu = "\n" + a[i][0] + " " +a[i][1] + " " + a[i][2];System.out.print(stu);if(a[i][5]==-1)    //若是链表中录取的最后一名break;            //则跳出循环,停止本类别的打印}}   }private static int[] getGrade(int[] a,int l,int h){//功能:根据数组中学生成绩,填写总分及等级信息 。l是录取线,h是优秀线。if(a[1]<l || a[2]<l){    //若德才有一项未达到录取线a[4] = 5;        //第五类考生,不予录取return a;}a[5] = -1;             //对录取学生,排序地址信息初始化a[3] = a[1] + a[2];     //对录取学生,计算德才总分if(a[1]>=h){    //若德分优秀a[4] = (a[2]>=h)?1:2;   //若才分也优秀,则为第一类,否则为第二类return a;}a[4] = (a[1]>=a[2])?3:4;    //若德分不优秀,但德分≥才分,则为第三类,否则其它考生为第四类return a;}private static int[][] getSort(int[][] a,int t,int yi){//功能:对数组中指定学生的成绩(以数组静态链表方式)排序并返回数组//参数 a[][] 学生信息数组 ;t 待排序学生角标 ;yi 待排序学生所属类别的第一名学生角标if(yi==-1)                    //如果当前学生所属类别中还没有学生return a;                   //则以待排序学生作为第一名,直接返回if(gradeCompare(a[t],a[yi])){        //如果待排序的学生是新的第一名a[t][5] = yi;                //待排序学生链接指向原先的第一名return a;}for(int i=yi,j=i;;i=a[i][5]){      //若链表中已经有至少一名学生,则正常进行排序if(gradeCompare(a[i],a[t])){    //若待排序学生成绩<当前对比学生成绩j=i;                            //用j记住当前对比学生角标if(a[i][5]==-1){                //若当前对比学生已经是最后一名a[i][5] = t;                    //将待排序学生插入到链表结尾break;                          //排序完毕,退出循环}}else{                          //若待排序学生成绩>当前对比学生成绩a[j][5] = t;                    //上一名的学生链接到待排序学生(此时j是链表中上一名学生的角标)a[t][5] = i;                    //待排序学生链接到当前对比学生break;                            //排序完毕,退出循环}}  return a;}private static boolean gradeCompare(int[] a,int[] b){//功能:比较两个等级相等的学生成绩,学生a是否排名比学生b更靠前if(a[3]!=b[3])        //若总分不相等return (a[3]>b[3]);         //则返回总分比较结果if(a[1]!=b[1])              //若德分不相等return (a[1]>b[1]);         //则返回德分比较结果return (a[0]<b[0]);              //最后按考号升序排序}
}

解法四 

我想上边的算法还是太复杂了,计算考生的排名需要计算类别,还要再比较总分、德分、考号,链表的排序也有些麻烦。我想应该可以有更简洁的方式。于是我想到根据考生的类别、总分、德分、考号来生成一个排序的序号(int类型),这个序号越大,考生的排名就应该越靠前。这样,只需要给每个考生计算生成一个序号并填写在数组中,之后在排序时的compare()方法中就只需要比较两个考生的排序序号就可以了。 

为了能够生成这样一个序号(能体现考生排名的序号),我的思路是,排序时优先看类别,那么类别这一项的优先级就越高,权重就应该越大。以此类推,考号的优先级最低,权重也最小。这个权重,是根据下一级排序项目中两个考生最大的差值计算的,在代码里有注释。这里的总分、德分是按照降序排序的,而类别号则是按照升序排序的。为了统一,我就写了一句“3-zongfen”来把类别号转换成一个降序排序的值。考号有8位,而一个int也就10位(十进制),如果把8位考号全都用上,那就不够用了。题目限定考生数量<10000,大胆猜测考号的前三位是不变的,一直是100 。那么就只截取考号的后五位来参与生成排序序号,前三位就丢掉。

此外,在这个算法中,代码整体变得更简洁了。从这一点上来说,这是我最满意的一个解法。

/*
功能:根据规则对给定考生成绩进行排序并输出
实现思路:用数组存储每个考生的信息,并用考生信息生成唯一序号实现排序。
时间复杂度   空间复杂度
*/
import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
class Main{public static void main(String[] args) throws IOException{//接收基本信息输入BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] arr1 = br.readLine().split(" +");int n = Integer.parseInt(arr1[0]);    //考生总数int l = Integer.parseInt(arr1[1]);    //最低录取分数线int h = Integer.parseInt(arr1[2]);    //优秀录取线//数组初始化Integer[][] a = new Integer[n][4];    //数组每一行代表一个考生,存储考号、德分、才分、排序序号//注意,因为要用java的Arrays.sort()排序算法,这里要写Integerint m = 0;                              //录取总人数String[] b = new String[3];           //接收当前考生的String信息//在线处理 接收每个学生信息并存入数组中for(int i=0;i<n;i++){               //在线处理每个考生的信息 i计数当前处理的是第几个考生b = br.readLine().split(" +");    //接收当前考生的信息for(int j = 0;j<=2;j++)             //将接收的当前考生信息转为int  m表示当前考生存储在考生数组的角标a[m][j] = Integer.parseInt(b[j]);if(a[m][1]>=l && a[m][2]>=l){          //如果当前考生为达到录取线的考生 (德分和才分都达到录取线)a[m][3] = getNum(a[m],l,h);       //根据当前考生已有信息,计算生成一个序号,用于排序m++;                             //则录取人数+1  (也就是说,考生数组中当前考生的信息予以保留,不会被覆盖)}}//数组排序Arrays.sort(a,0,m,new Comparator<Integer[]>() {         //考生数组的0-m角标正是存储的录取学生的信息public int compare(Integer[] b, Integer[] a) {  //new一个Comparator匿名内部类,重写compare方法return (a[3]>b[3])?1:-1;                    //通过比较考生的排序序号来进行排序 序号大者排名靠前}});//打印输出System.out.print(m);                //输出录取总人数if(m!=0)                            //若是录取人数为0,则直接返回 ,若是录取人数不为零,则遍历数组打印考生信息for(int i=0;i<m;i++)                //输出m个录取考生的信息System.out.print( "\n" + a[i][0] + " " +a[i][1] + " " + a[i][2]);}private static Integer getNum(Integer[] a,int l,int h){//功能:根据考生已有信息,计算生成一个序号,用于排序//参数:int[] a 当前考生信息数组;int l最低录取线; int h 优先录取线//声明变量int zongfen=0, dengji = 0, xuhao = 0;       //用于存储当前考生的总分、等级(类别)、排序序号//计算并填写当前考生的总分zongfen = a[1] + a[2];         //对录取学生,计算德才总分//计算并填写当前考生的等级if(a[1]>=h)                 //若德分优秀dengji = (a[2]>=h)?1:2;       //若才分也优秀,则为第一类,否则为第二类else                        //若德分不优秀dengji = (a[1]>=a[2])?3:4;    //但德分≥才分,则为第三类,否则其它考生为第四类//计算生成用于排序的序号xuhao = (3-dengji) * 81 * 41 + zongfen * 41 + a[1];    //取值范围不超过[0,18263]  3-dengji是把等级转化为一个等级越高就越大的值xuhao = xuhao * 10000 - (a[0] % 10000);             //把考号后五位也整合在内,生成一个唯一的排序序号  因为考号是升序排列,所以相减/*采用的方法是给等级、总分、德分、考号赋予不同的权重,由此生成的序号就能体现排序次序。能录取的考生AB,德分相差最大是100-60=40,那么就给总分的权重设置为41;能录取的考生AB,总分相差最大是200-120=80,那么就给等级设置的权重为81;因为考号是8位,比较长,一个int也就10位二进制,因此就单独处理一下,已知考生数不超过10000,那么大胆猜测考号前三位是不变的,因此只取考号后五位来生成序号。*/return xuhao;}}

 结语

Java解法总结

以上用java的四种解法都会超时,难道这道题必须用C语言才能不超时吗?题目设置的是不限制语言,这有点不严谨。(后续:我去查看了平台的说明文档,它说,选择合适的编程语言也是能力的一部分,内存和时间限制标准对各个编程语言都设置的是相同的。好吧。)

为了测试用java解这道题的可行性,我写了一个简单的程序,仅仅读取所有考生信息的输入,而不做任何处理。即便是这样一个显然时间复杂度为线性的程序,测试仍然是三个点超时。也就是说,只要用java,连把所有考生信息都读取一遍都做不到,更别想着排序及打印了。代码如下。

/*
功能:测试用java是否能在线性复杂度内读取完所有考生信息
实现思路:只读取每个考生的信息,不做任何处理
时间复杂度 O(n)   空间复杂度
*/
import java.io.*;
class Main{public static void main(String[] args) throws IOException{//接收基本信息输入BufferedReader br = new BufferedReader(new InputStreamReader(System.in));    //获取输入流对象String[] arr1 = br.readLine().split(" +");        //读取基本信息(考生总数、最低录取线、优先录取线)int n = Integer.parseInt(arr1[0]);                //将考生总数转为int//声明变量String[] b = new String[3];           //用于接收当前考生的String信息//在线处理 接收每个学生信息并存入数组中for(int i=0;i<n;i++)                 //接收每个考生的信息 i计数当前处理的是第几个考生b = br.readLine().split(" +");    //接收当前考生的信息       }
}

C语言代码

本来打算放弃这道题了。但是又有点不甘心。于是决定把Java程序改写为C语言程序。这部分我借助了AI助手,把上述Java的解法一改写为C语言程序了。所有测试点全部通过!看来我的解法没问题,只是要用C语言而不能用Java。代码如下。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct {int id;      // 考号int de, cai; // 德分和才分int total;   // 总分int type;    // 考生类别int next;    // 链表中下一个考生的角标
} Student;// 比较函数,用于排序
int compare(const void *a, const void *b) {Student *s1 = (Student*)a;Student *s2 = (Student*)b;if (s1->type != s2->type) {return s2->type - s1->type;} else if (s1->total != s2->total) {return s1->total - s2->total;} else if (s1->de != s2->de) {return s1->de - s2->de;} else {return s2->id - s1->id;}
}int main() {int n, l, h;  // 考生总数,最低录取分数线,优秀录取线scanf("%d %d %d", &n, &l, &h);Student *students = (Student*)malloc(n * sizeof(Student));  // 动态分配内存int m = 0;  // 录取的学生数for (int i = 0; i < n; i++) {int id, de, cai;scanf("%d %d %d", &id, &de, &cai);int total = de + cai;if (de >= l && cai >= l) {  // 满足最低录取线students[m].id = id;students[m].de = de;students[m].cai = cai;students[m].total = total;if (de >= h && cai >= h) {  // 满足优秀录取线students[m].type = 1;  // 第一类考生} else if (de >= h && cai < h) {students[m].type = 2;  // 第二类考生} else if (de < h && cai < h && de >= cai) {students[m].type = 3;  // 第三类考生} else {students[m].type = 4;  // 第四类考生}students[m].next = -1;  // 初始化为-1,表示没有下一个学生m++;}}// 按照给定规则排序qsort(students, m, sizeof(Student), compare);// 构建静态链表int head = -1;  // 头结点for (int i = 0; i < m; i++) {if (students[i].type != 5) {  // 只处理可录取的学生students[i].next = head;head = i;}}// 输出结果printf("%d", m);for (int i = head; i != -1; i = students[i].next) {printf("\n%d %d %d", students[i].id, students[i].de, students[i].cai);}free(students);  // 释放内存return 0;
}

完毕。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/150838.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

.net framework中webapi使用swagger进行接口文档展示

第一步&#xff1a;在nuget程序包管理中搜索“Swashbuckle”包&#xff0c;然后进行安装&#xff08;注&#xff1a;如果是.net core api请安装Sawshbuckle aspnetcore&#xff09;。 第二步&#xff1a;打开项目App_Start文件夹&#xff0c;修改SwaggerConfig.cs配置文件 我这…

Android:实现手机前后摄像头预览同开

效果展示 一.概述 本博文讲解如何实现手机前后两颗摄像头同时预览并显示 我之前博文《OpenGLES&#xff1a;GLSurfaceView实现Android Camera预览》对单颗摄像头预览做过详细讲解&#xff0c;而前后双摄实现原理其实也并不复杂&#xff0c;粗糙点说就是把单摄像头预览流程写两…

安全防御—密码学

1. 什么是APT&#xff1f; APT&#xff08;Advanced Persistent Threat&#xff09;是指高级持续性威胁&#xff0c;本质是针对性攻击。 利用先进的攻击手段对特定目标进行长期持续性网络攻击的攻击形式&#xff0c;APT攻击的原理相对于其他攻击形式更为高级和先进&#xff0c;…

Linux友人帐之账号用户管理

一、账号管理 1.1简介 Linux系统是一个多用户多任务的分时操作系统&#xff0c;任何一个要使用系统资源的用户&#xff0c;都必须首先向系统管理员申请一个账号&#xff0c;然后以这个账号的身份进入系统。 用户的账号一方面可以帮助系统管理员对使用系统的用户进行跟踪&#…

RabbitMQ学习笔记(下):延迟队列,发布确认高级,备份交换机

十、延迟队列 延迟队列 概念&#xff1a; 延迟队列使用场景&#xff1a; 流程图&#xff1a; 延迟队列整合Springboot 导入依赖&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot…

MyCat安装文档

JDK安装 JDK具体安装步骤如下&#xff1a; 1. 上传安装包 使用FinalShell自带的上传工具将jdk的二进制发布包上传到Linux 由于上述在进行文件上传时&#xff0c;选择的上传目录为根目录 /&#xff0c;上传完毕后&#xff0c;我们执行指令 cd / 切换到根目录下&#xff0c;查…

六款Linux常用远程连接工具

1、Xshell 介绍&#xff1a; xshell是一个非常强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Windows平台的TELNET 协议。Xshell可以在Windows界面下用来访问远端不同系统下的服务器&#xff0c;从而比较好的达到远程控制终端的目的。&#xff08;也是我目前使用的…

15-自动化测试——理论知识

目录 1.什么是自动化测试&#xff1f; 2.常见的自动化测试分类 2.1.单元测试&#xff08;Java、Python&#xff09; 2.2.接口测试&#xff08;Java、Python&#xff09; 2.3.UI测试&#xff08;移动端、网站&#xff09; 3.如何实施自动化测试&#xff1f; 4.自动化测试…

力扣第572题 另一棵树的子树 c++深度(DFS)注释版

题目 572. 另一棵树的子树 简单 给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有…

(高阶) Redis 7 第21讲 IO多路复用模型 完结篇

🌹 以下分享 Redis IO多路复用模型,如有问题请指教。🌹🌹 如你对技术也感兴趣,欢迎交流。🌹🌹🌹 如有对阁下帮助,请👍点赞💖收藏🐱‍🏍分享😀 IO多路复用模型是什么 I/O:网络IO 多路:多个客户端连接(连接即套接字描述符,即socket或channel),指…

hive 常用函数

1.分位数 percentile_approx(DOUBLE col, p [, B]) Returns an approximate pth percentile of a numeric column (including floating point types) in the group 含义: 在col列中返回p%的分位数 select percentile_approx( arr_id , 0.5 )from (selectarr_idfrom(selecta…

【赠书活动】Excel透视表的简单应用

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

【网络】路由器和交换机的区别

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的帮助&#x1…

微服务技术栈-Nacos配置管理和Feign远程调用

文章目录 前言一、统一配置管理1.添加配置文件2.微服务拉取配置3.配置共享 三、Feign远程调用总结 前言 在上篇文章中介绍了微服务技术栈中Nacos这个组件的概念&#xff0c;Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。同时我们将学习一种新的远程调用方式…

【Linux】信号屏蔽与信号捕捉的原理与实现(附图解与代码)

这一篇的篇幅可能有点长&#xff0c;如果已经了解了以下两个知识点的同学可以自行跳到第三部分——信号屏蔽的实现。 不太了解的同学希望你们能够静下心来看完&#xff0c;相信一定会有不小的收获。那么话不多说&#xff0c;我们这就开始啦&#xff01;&#xff01;&#xff0…

git与github的交互(文件与文件夹的上传)

git与github的交互&#xff08;文件与文件夹的上传&#xff09; 准备&#xff1a;gitHub账号&#xff08;创建一个新项目&#xff09;与Git软件的安装 一&#xff1a;开启公钥SSH登录&#xff08;之前配置过就跳过&#xff09; 1.安装SSH 在本地新创建文件夹负责装载项目&a…

(c语言)经典bug

#include<stdio.h> //经典bug int main() { int i 0; int arr[10] {1,2,3,4,5,6,7,8,9,10}; for (i 0; i < 12; i) //越界访问 { arr[i] 0; printf("hehe\n"); } return 0; } 注&#xff1a;输出结果为死循…

[论文工具] LaTeX论文SVG和EPS矢量图转换方法详解

祝大家中秋国庆双节快乐&#xff01; 回过头来&#xff0c;我们在编程过程中&#xff0c;经常会遇到各种各样的问题。然而&#xff0c;很多问题都无法解决&#xff0c;网上夹杂着各种冗余的回答&#xff0c;也缺乏系统的实战技巧归纳。为更好地从事科学研究和编程学习&#xff…

螺杆支撑座有什么优势?

螺杆支撑座是机械设备中重要的支撑部件&#xff0c;其主要作用是支撑和固定螺杆&#xff0c;以确保机械设备的正常运行。以下是螺杆支撑座的使用优势&#xff1a; 1、支撑稳定&#xff1a;螺杆支撑座采用高品质钢材制作而成&#xff0c;具有较高的强度和刚度&#xff0c;能够为…

FR问题记录

1. 问题&#xff1a;下拉框搜索查询时&#xff0c;出现所有的搜索信息 解决方法&#xff1a;使用数据集sql进行数据筛选 在数据库查询中使用where条件筛选&#xff0c;如 ${IF(LEN(所属省份) 0,"","AND province in (" 所属省份 ")")}参考…