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

前言

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

这道题用java解,我试了三种解法,不断优化,但始终是三个测试点通过、三个测试点超时。我把我的代码放在这里,做个参考吧。

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写了三种解法,测试结果都是三个测试点正确、三个测试点超时。研究半天也没搞明白到底为什么超时(难道是只能用C语言才不会超时?),发出来做个参考吧。

解法一  

用二维数组存储学生信息,同时用这个数组作为静态链表来排序(定义一个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的排序算法,在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]);              //最后按考号升序排序}
}

结语

以上用java的三种解法都会超时,难道这道题必须用C语言才能不超时吗?也许可以根据考生成绩生成一个唯一的序号,再利用这个序号进行数组的快速排序?等试验了再回来更新吧。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

获取上证50的所有股票代码

我们可以从网页&#xff08;板块 - 上证50_ - 股票行情中心 - 搜狐证券&#xff09;中获取&#xff0c; 然后打印出来&#xff1a; import requests from bs4 import BeautifulSoupurl "https://q.stock.sohu.com/cn/bk_4272.shtml" response requests.get(url) …

junit @ExcludePackages排除多个包

在JUnit中&#xff0c;可以使用ExcludePackages注解来排除多个包。该注解可以用在测试类或测试方法上。 如果要排除多个包&#xff0c;可以在ExcludePackages注解的value属性中使用数组来指定要排除的包名。例如&#xff0c;要排除包com.example.package1和com.example.packag…

秋招问题记录贴

最近面试有点多&#xff0c;没来的及写面经&#xff0c;就单独开个帖子记录一下碰到的一些不懂的技术问题&#xff1a; AQS中两个队列如何工作&#xff0c;这个结合os中阻塞和就绪两种情况讲分布式的理解&#xff0c;这个问的频率很高nacos怎么进行服务注册和发现的mysql什么情…

TcpConnection的读写操作【深度剖析】

文章目录 前言一、TcpConnection的读二、TcpConnection的写三、TcpConnection的关闭 前言 今天总结TcpConnection类的读写事件。 一、TcpConnection的读 当Poller检测到套接字的Channel处于可读状态时&#xff0c;会调用Channel的回调函数&#xff0c;回调函数中根据不同激活…

treectrl类封装 2023/8/13 下午4:07:35

2023/8/13 下午4:07:35 treectrl类封装 2023/8/13 下午4:07:53 TreeCtrl 类是一个常用的图形用户界面控件,用于实现树形结构的展示和交互。以下是一个简单的 TreeCtrl 类的封装示例: python import wxclass MyTreeCtrl(wx.TreeCtrl):def __init__(self, parent):super()…

java限流

限流可以使用redis的过期时间自动过期限流的key&#xff0c;&#xff0c; 也可以使用一个定时器&#xff0c;在指定时间后清除这个key&#xff0c;&#xff0c;比如Timer Timer的使用 Timer timer new Timer() timer.schedule(timerTast,delay,period) public static void …

mysql面试题13:MySQL中什么是异步复制?底层实现?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:讲一讲mysql中什么是异步复制?底层实现? MySQL中的异步复制(Asynchronous Replication)是一种复制模式,主服务器将数据写入二进制日志后,无…

mysql面试题14:讲一讲MySQL中什么是全同步复制?底层实现?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:讲一讲mysql中什么是全同步复制?底层实现? MySQL中的全同步复制(Synchronous Replication)是一种复制模式,主服务器在写操作完成后,必须等待…

AI配套的技术: 矢量数据库的概念

一、说明 随着人工智能的快速采用和围绕大型语言模型发生的创新&#xff0c;我们需要在所有这些的中心&#xff0c;能够获取大量数据&#xff0c;将其上下文化&#xff0c;处理它&#xff0c;并使其能够有意义地搜索。 为原生整合生成式 AI 功能而构建的生成式 AI 流程和应用程…

JUC第十四讲:JUC锁: ReentrantReadWriteLock详解

JUC第十四讲&#xff1a;JUC锁: ReentrantReadWriteLock详解 本文是JUC第十四讲&#xff1a;JUC锁 - ReentrantReadWriteLock详解。ReentrantReadWriteLock表示可重入读写锁&#xff0c;ReentrantReadWriteLock中包含了两种锁&#xff0c;读锁ReadLock和写锁WriteLock&#xff…

ES6中的let、const

let ES6中新增了let命令&#xff0c;用来声明变量&#xff0c;和var类似但是也有一定的区别 1. 块级作用域 只能在当前作用域内使用&#xff0c;各个作用域不能互相使用&#xff0c;否则会报错。 {let a 1;var b 1; } console.log(a); // 会报错 console.log(b); // 1为什…

Day-05 CentOS7.5 安装docker

参考 &#xff1a; Install Docker Engine on CentOS | Docker DocsLearn how to install Docker Engine on CentOS. These instructions cover the different installation methods, how to uninstall, and next steps.https://docs.docker.com/engine/install/centos/ Doc…

iOS AVAudioSession 详解

iOS AVAudioSession 详解 - 简书 默认没有options&#xff0c;category 7种即可满足条件 - (BOOL)setCategory:(AVAudioSessionCategory)category error:(NSError **)outError API_AVAILABLE(ios(3.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); 有options&#xff…

实战型开发--3/3,clean code

编程的纯粹 hmmm&#xff0c;一开始在这个环节想聊一些具体的点&#xff0c;其实也就是《clean code》这本书中的点&#xff0c;但这个就还是更流于表面&#xff1b; 因为编码的过程&#xff0c;就更接近于运动员打球&#xff0c;艺术家绘画&#xff0c;棋手下棋的过程&#x…

Elasticsearch基础篇(四):Elasticsearch7.x的官方文档学习(Set up Elasticsearch)

Set up Elasticsearch 1 Configuring Elasticsearch(配置 Elasticsearch)1.1 Setting JVM Options(设置JVM选项)1.2 Secure Settings(安全设置)Introduction(介绍)Using the Keystore(使用密钥库)Applying Changes(应用更改)Reloadable Secure Settings(可重新加载的安全设置)R…

GPT系列论文解读:GPT-1

GPT系列 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是一系列基于Transformer架构的预训练语言模型&#xff0c;由OpenAI开发。以下是GPT系列的主要模型&#xff1a; GPT&#xff1a;GPT-1是于2018年发布的第一个版本&#xff0c;它使用了12个Transformer…

软件设计师_计算机网络_学习笔记

文章目录 4.1 网路技术标准与协议4.1.1 协议4.1.2 DHCP4.1.3 DNS的两种查询方式 4.2 计算机网络的分类4.2.1 拓扑结构 4.3 网络规划与设计4.3.1 遵循的原则4.3.2 逻辑网络设计4.3.3 物理网络设计4.3.4 分层设计 4.4 IP地址与子网划分4.4.1 子网划分4.4.2 特殊IP 4.5 HTML4.6 无…

【MySQL】表的约束(二)

文章目录 一. 主键二. 自增长三. 唯一值四. 外键结束语 一. 主键 主键primary key 用来唯一的约束该字段里面的数据&#xff0c;不能重复&#xff0c;不能为空&#xff0c;一张表最多只能有一个主键&#xff0c;主键所在的列通常是整数类型 创建表时直接在字段上指定主键 mysq…

在2023年使用Unity2021从Built-in升级到Urp可行么

因为最近在做WEbgl平台&#xff0c;所以某些不可抗力原因&#xff0c;需要使用Unity2021开发&#xff0c;又由于不可明说原因&#xff0c;想用Urp&#xff0c;怎么办&#xff1f; 目录 创建RenderAsset 关联Asset 暴力转换&#xff08;Menu->Edit&#xff09; 单个文件…

栈的基本操作(数据结构)

顺序栈的基本操作 #include <stdlib.h> #include <iostream> #include <stdio.h> #define MaxSize 10typedef struct{int data[MaxSize];int top; }SqStack;//初始化栈 void InitStack(SqStack &S){S.top -1; } //判断栈空 bool StackEmpty(SqStack S)…