算法奇妙屋(四十五)-CCPC备战之旅-1

文章目录

  • [2024秦皇岛-Problem C](#2024秦皇岛-Problem C)
    • [1. 题目解析](#1. 题目解析)
    • [2. 算法原理](#2. 算法原理)
    • [3. 代码](#3. 代码)

2024秦皇岛-Problem C

1. 题目解析

对于竞赛的题目相信我不用多说, 最最最重要的就是理解题意, 哪怕知道是坨屎也得吃掉

2. 算法原理

典型的区间贪心问题, 但在这里仍需排序+双指针+小根堆的辅助, 做这道题有很多收获
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 + " ");
        }
    }
}
相关推荐
ch.ju20 小时前
Java Programming Chapter 2-Nested call
java·开发语言
yqcoder20 小时前
JavaScript 内存揭秘:堆(Heap) vs 栈(Stack)
开发语言·javascript·ecmascript
覆东流20 小时前
第11天:python字典基础
开发语言·后端·python
河阿里20 小时前
深入理解LRU缓存机制:从原理到应用(C++实现
开发语言·c++·缓存
05候补工程师20 小时前
【408考研·OS】核心考点:中断分类、线程模型 (KLT/ULT) 与调度算法方法论总结
经验分享·笔记·考研·算法
xyq202420 小时前
PHP Date
开发语言
杨充20 小时前
03.计算机基础CPU设计
java·开发语言
无所事事O_o20 小时前
【监控报警体系建设】监控标准与最佳实践
java·架构·监控
多加点辣也没关系20 小时前
数据结构与算法|第十二章:图
数据结构·算法
gergul21 小时前
python venv虚拟环境复制
linux·开发语言·python