存在三超时问题的。。。
题目分析
第一行给出三个数据
1.总共考生人数 N(≤10^5)
2.录取分数线 L
3.高分线H
随后给出N行考生信息 准考证号 德分 才分。
本题要求对全部考生成绩进行分类并排名:
下分为四类
- 第一类:德分和才分均不低于高分线
- 第二类:才分低于高分线但德分不低于高分线
- 第三类:德才分均低于高分线,但是德分不低于才分的考生
- 第四类:德才分达到最低线的考生
排名顺序要求:
- 学生等级升序排行 等级一样总分降序;
- 总分相同时,按其德分降序排列;
- 若德分也并列,则按准考证号升序输出。
input:N(总考生数) ,L(录取线),H(高分线)。随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分,其中准考证号为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。
output:第一行 最低分数线的考生人数 M (循环判断计数)
随后M行要求按照以上排名顺序要求 进行输出
题目输入保证每个测试存在唯一解。
解决方案
个人通过 数组进行记录 考生信息与成绩(同时对考生德才分运用判断语句 划分四类达标)。排序,通过java给出的 Collections.sort函数,编写比较器进行自动排序(速度也慢)。
重点:比较器Comparator 函数编写 返回大于0表示正序,小于0表示逆序。
**Collections.sort函数:**底部的实现主要思想是归并排序,Java1.7后进行了优化,优先去找到其中顺序部分,对其他的部分在进行排序,并与已知的进行归并排序。
(此处理解自:https://blog.csdn.net/u011410529/article/details/56668545)
代码
import java.util.*;
/**
* @Description: https://pintia.cn/problem-sets/994805260223102976/problems/994805307551629312
* 1015 德才论 (25分)
* java 超时!!!
* @Author: zyb
* @Date: 2021-01-07
*/
public class Main {
public static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
int N = input.nextInt(); //考生总数
int L = input.nextInt(); //及格线
int H = input.nextInt(); //高分线
int M = 0; //通过人数
//准考证号 德分 才分
int[][] grade = new int[N][4];
for (int i = 0; i < N; i++) {
for (int j = 0; j < 3; j++) {
grade[i][j] = input.nextInt();
}
/* 进行学生等级分类x
第一类:德分和才分均不低于高分线
第二类:才分不到但德分到高分线
第三类:德才分均低于高分线,但是德分不低于才分的考生
第四类:德才分达到最低线的考生
*/
if (grade[i][1] >= L && grade[i][2] >= L) {
M++;
if (grade[i][1] >= H && grade[i][2] >= H) {
grade[i][3] = 1;
} else if (grade[i][1] >= H && grade[i][2] < H) {
grade[i][3] = 2;
} else if (grade[i][1] < H && grade[i][2] < H) {
if (grade[i][1] >= grade[i][2]) {
grade[i][3] = 3;
} else {
grade[i][3] = 4;
}
} else {
grade[i][3] = 4;
}
}
}
ArrayList<int[]> rank = new ArrayList<>();
for (int i = 0; i < grade.length; i++) {
if (grade[i][3] == 0) continue;
rank.add(grade[i]);
}
//编写排血规则函数 (重点部分)
Collections.sort(rank, new Comparator<int[]>() {
@Override
//返回大于0表示正序,小于0表示逆序
public int compare(int[] o1, int[] o2) {
/*学生等级升序排行 等级一样总分从高到低;
总分相同时,按其德分降序排列;
若德分也并列,则按准考证号的升序输出。
*/
if (o1[3] > o2[3]) //等级升序排行
return 1;
else if (o1[3] < o2[3])
return -1;
else if (o1[3] == o2[3]) {
//等级相同 总分降序排行
if (o1[1] + o1[2] > o2[1] + o2[2]) {
return -1;
} else if (o1[1] + o1[2] < o2[1] + o2[2]) {
return 1;
} else if (o1[1] + o1[2] == o2[1] + o2[2]) { //总分相同按德分降序
if (o1[1] > o2[1]) {
return -1;
} else if (o1[1] < o2[1]) {
return 1;
} else if (o1[1] == o2[1]) { // 德分相同按准考证号的升序输出。
if (o1[0] > o2[0]) {
return 1;
} else if (o1[0] < o2[0]) {
return -1;
}
}
}
}
return 0;
}
});
System.out.println(M);
//进行格式化输出
rank.forEach((r) -> {
System.out.println(r[0] + " " + r[1] + " " + r[2]);
});
}
}
最开始是打算用 数组进行排序,并不是很好操作就偷懒用了Arraylist。