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

这篇具有很好参考价值的文章主要介绍了【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]);        //将考生信息转为int
            a[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>b
            return true;
        if(a[3]<b[3])      //若总分a<b
            return false;
                           //若ab总分相同
        if(a[1]>b[1])      //若德分a>b
            return true;
        if(a[1]<b[1])      //若德分a<b
            return 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>b
                    return 1;
                if(a[3]<b[3])      //若总分a<b
                    return -1;
                                   //若ab总分相同
                if(a[1]>b[1])      //若德分a>b
                    return 1;
                if(a[1]<b[1])      //若德分a<b
                    return -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++){           //数组初始化为-1
            yi[i] = -1;
        }
        //在线处理 接收每个学生信息并排序存入数组中
        for(int i=0,temp=-1;i<n;i++){        //在线处理每个考生的信息
            b = br.readLine().split(" +");    //接收当前考生的信息
            a[i][0] = Integer.parseInt(b[0]);        //将考生信息转为int
            a[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()排序算法,这里要写Integer
        int 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;
}

完毕。文章来源地址https://www.toymoban.com/news/detail-728987.html

到了这里,关于【Java】PAT(Basic Level) Practice(中文) 1015德才论的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PAT (Advanced Level) 甲级 1004 Counting Leaves

    点此查看所有题目集 A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.   Input Specification: Each input file contains one test case. Each case starts with a line containing 0N100, the number of nodes in a tree, and M (N), the number of non-leaf nodes. Then M lines follow, ea

    2024年02月12日
    浏览(41)
  • PAT (Advanced Level) 甲级 1005 Spell It Right

    点此查看所有题目集 Given a non-negative integer N, your task is to compute the sum of all the digits of N, and output every digit of the sum in English.   Input Specification: Each input file contains one test case. Each case occupies one line which contains an N (≤10^100).   Output Specification: For each test case, output in one line the d

    2024年02月12日
    浏览(54)
  • Elasticsearch:从 Java High Level Rest Client 切换到新的 Java API Client

    作者:David Pilato 我经常在讨论中看到与 Java API 客户端使用相关的问题。 为此,我在 2019 年启动了一个 GitHub 存储库,以提供一些实际有效的代码示例并回答社区提出的问题。 从那时起,高级 Rest 客户端 (High Level Rest Cliet - HLRC) 已被弃用,并且新的 Java API 客户端已发布。 为了

    2024年03月19日
    浏览(49)
  • SpringBoot整合ElasticSearch之Java High Level REST Client

    1 搭建SpringBoot工程 2 引入ElasticSearch相关坐标。 3 编写核心配置类 编写核心配置文件: 这里可以不写在配置,可以直接写在代码中,只是一般都是写在配置文件中 编写核心配置类 4 测试客户端对象 记得把maven的单元测试关了 注意:使用@Autowired注入RestHighLevelClient 如果报红线

    2024年02月05日
    浏览(52)
  • logging.level的含义及设置 【java 日志 (logback、log4j)】

    日志级别 tracedebuginfowarnerrorfatal 常用的有:debug,info,warn,error 通常我们想设置日志级别,会用到 logging.level.root=info logging.level设置日志级别,后面跟生效的区域。root表示整个项目。 也可以写某个包,或者某个类。 例如:logging.level.com.ali.service=error。在com.ali.service包下所有

    2024年02月10日
    浏览(46)
  • elasaticsearch新版java客户端ElasticsearchClient详细教程,支持响应式编程,Lambda表达式,兼容旧版High Level Rest Client

    elasaticsearch新版java客户端详细教程,支持响应式编程,Lambda表达式。兼容旧版High Level Rest Client。网上相关教程少,我在这里出一个。elasaticsearch相关安装这里不介绍了 有几种方式,这里介绍两种,如果不考虑之前旧版High Level Rest Client的客户端采用第一种就行 阻塞和异步客户

    2023年04月15日
    浏览(38)
  • 【分布式共识算法】Basic Paxos 算法

    basic paxos算法:描述的是多个节点就某个值达成共识。 muti-paxos 算法:描述的是执行多个basic paxos实例,就一系列值达成共识。 共识其实,比如当多个客户端请求服务器,修改同一个值X 多个阶段达成共识。 角色:提议者、接受者、学习者。 提议者 :说白了就是提出一个值,

    2024年02月12日
    浏览(29)
  • 算法学习-链表-level1

    part1:单向链表 1、构造 2、创建节点并初始化 3、基础操作-增删 首先写出打印函数方便后续的检验 接下来写出获取链表长度的函数,目的是检验接下来插入时的边界的的检验 准备工作结束~  那么接下来正式开始链表的增删操作 这里的增加节点的操作需要注意的是对于每一种

    2024年02月14日
    浏览(42)
  • Java如何解决中文乱码

    在Java中,要解决中文乱码问题,可以使用以下几种方法: 如有疑问加入Q群:747125137 1. 使用正确字符编码进行读写操作:确保在读取和写入中文数据使用正确的字符编码。常用的字符编码包括UTF-8、、UTF-16等。可以使用`InputStreamReader`和`OutputStreamWriter`来指定字符编码。   示例

    2024年02月07日
    浏览(50)
  • 【Java 进阶篇】解决Java Web应用中请求参数中文乱码问题

    在Java Web应用开发中,处理请求参数时经常会遇到中文乱码的问题。当浏览器向服务器发送包含中文字符的请求参数时,如果不正确处理,可能会导致乱码问题,使得参数无法正确解析和显示。本文将详细探讨Java Web应用中请求参数中文乱码问题,以及如何解决这个问题。 中

    2024年02月08日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包