找出作弊的人
题目描述
公司组织了一次考试,现在考试结果出来了,想看一下有没人存在作弊行为,但是员工太多了,需要先对员工进行一次过滤,再进一步确定是否存在作弊行为。
过滤的规则为:找到分差最小的员工ID对(p1,p2)列表,要求p1<p2
员工个数取值范国:O<n<100000
员工ID为整数,取值范围:0<=n<=100000
考试成绩为整数,取值范围:0<=score<=300
输入描述
员工的ID及考试分数
输出描述
分差最小的员工ID对(p1,p2)列表,要求p1<p2。每一行代表一个集合,每个集合内的员工ID按顺序排列,多行结果也以员工对中p1值大小升序排列(如果p1相同则p2升序)。
样例1
输入:
5
1 90
2 91
3 95
4 96
5 100
输出:
1 2
3 4
解释:
输入:第一行为员工个数n,后续的n行第一个数值为员工ID,第二个数值为员工考试分数
输出:员工1和员工2的分差为1,员工3和员工4的分差也为1,因此最终结果为
1 2
3 4
样例2
输入:
5
1 90
2 91
3 92
4 85
5 86
输出:
1 2
2 3
4 5
代码
public class FindTheChief {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = Integer.parseInt(in.nextLine());
List<TestResult> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
String l = in.nextLine();
String[] arr = l.split(" ");
list.add(new TestResult(Integer.parseInt(arr[0]), Integer.parseInt(arr[1])));
}
// 按分数大到小排序,排序完后,最小差距的分数一定是最近的两个
list.sort(Comparator.comparingInt(TestResult::getScore).reversed());
// treemap默认是自然顺序
Map<Integer, Integer> map = new TreeMap<>();
// 初始化gap
int minGap = Integer.MAX_VALUE;
for (int i = 0; i < list.size() - 1; i++) {
int gap = list.get(i).score - list.get(i + 1).score;
if (gap < minGap) {
minGap = gap;
map.clear();
add2Map(map, list, i);
continue;
}
if (gap == minGap) {
add2Map(map, list, i);
}
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
private static void add2Map(Map<Integer, Integer> map, List<TestResult> list, int index) {
if (list.get(index).id < list.get(index + 1).id) {
map.put(list.get(index).id, list.get(index + 1).id);
} else {
map.put(list.get(index + 1).id, list.get(index).id);
}
}
static class TestResult {
int id;
int score;
TestResult(int id, int score) {
this.id = id;
this.score = score;
}
public int getScore() {
return score;
}
}
}