算法奇妙屋(四十五)-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 + " ");
        }
    }
}
相关推荐
无小道2 小时前
算法——找规律
算法·规律
songcream12 小时前
Spring Boot资料整理
java·spring boot·后端
源码宝2 小时前
新一代医院信息系统云HIS,多租户共享,java版HIS+EMR+LIS全套源码
java·大数据·源码·云his·his系统·源代码·医院信息系统
U盘失踪了2 小时前
go 常量
开发语言·后端·golang
techdashen2 小时前
Go 的新垃圾回收器 Green Tea:一个降低GC CPU开销的大工程
开发语言·后端·golang
Java面试题总结2 小时前
BCrypt密码加密
开发语言·python
cici158742 小时前
C# 五子棋小游戏源码(人机对战)
开发语言·单片机·c#
iiiiyu2 小时前
面向对象高级接口的综合案例
java·开发语言·数据结构·编程语言
fzil0012 小时前
让 AI 自己协作 —— 多智能体(Swarm)系统的设计与实现
java·开发语言·人工智能·ubuntu