典型的区间贪心问题, 但在这里仍需排序+双指针+小根堆的辅助, 做这道题有很多收获 1. 竞赛Java的输入使用的是BufferedReader+StringTokenizer的组合,
① BufferedReader br = new BufferedReader(new InputStreamReader(System.in))实例化一个读入流 ② StringTokenizer st = new StringTokenizer(br.readLine()) 用来读取一行, 即读取到回车/换行/回车+换行符号时停止, 这一行中可以包含其他空白字符 ③ st.nextToken() 用来用来读取一个个token(单词), 每个token通过空白字符分割, 空白字符指的是空格 ()、制表符 (\t)、换行符 (\n)、回车符 (\r)、换页符 (\f) 2. 对于竞赛中的区间, 不一定采用二维数组来存储, 也可以使用两个数组来映射
3. 学到了两种种新的比较器使用方式
① Integer[] order数组要根据l[] 数组中的元素来进行升序排列,
Arrays.sort(order, Comparator.comparingInt(i -> l[i])); ② 要进行降序排列, 将升序比较器反转即可
Arrays.sort(order, Comparator.comparingInt(i -> l[(int) i]).reversed()); ③ 降序/升序的另一种方式, 通过Integer.compare方法
Arrays.sort(order, (a, b) -> Integer.compare(l[a], l[b]))
3. 代码
java复制代码
package problem;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
/**
* Created with IntelliJ IDEA.
* Description:
* User: ran
* Date: 2026-04-15
* Time: 0:30
*/
public class P_C {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()); // 读取第一行
int n = Integer.parseInt(st.nextToken()); // 第一个token就是 n
// 建立l和r数组
int[] l = new int[n];
int[] r = new int[n];
Integer[] order = new Integer[n];
// 读入到数组, 顺手初始化order
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
l[i] = Integer.parseInt(st.nextToken());
r[i] = Integer.parseInt(st.nextToken());
order[i] = i;
}
List<Integer> ret = new ArrayList<>();
// 按照l的元素来, 来对order排序
Arrays.sort(order, Comparator.comparingInt(i -> l[i]));
// 按照r的元素来升序, 新学的排序方式
PriorityQueue<Integer> heap = new PriorityQueue<>(Comparator.comparingInt(i -> r[i]));
//外层循环
int i = 0, p = 0;
while (i < n || !heap.isEmpty()) {
// 循环1
while (i < n && l[order[i]] <= p) {
heap.add(order[i]);// 把满足的坐标加入堆
i++;
}
// 循环2
boolean tag = false;
while (!heap.isEmpty()) {
int index = heap.poll();
if (r[index] >= p) {
tag = true;
ret.add(index);
p++;
break;
}
}
if (!tag) {
break;
}
}
System.out.println(ret.size());
for (int x : ret) {
System.out.print(x + 1 + " ");
}
}
}