题解:AcWing 906 区间分组

【题目来源】

AcWing:906. 区间分组 - AcWing题库

【题目描述】

给定 \(N\) 个闭区间 \([a_i,b_i]\),请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。

输出最小组数。

【输入】

第一行包含整数 \(N\),表示区间数。

接下来 \(N\) 行,每行包含两个整数 \(a_i,b_i\),表示一个区间的两个端点。

【输出】

输出一个整数,表示最小组数。

【输入样例】

3
-1 1
2 4
3 5

【输出样例】

2

【算法标签】

《AcWing 906 区间分组》 #贪心#

【代码详解】

#include <bits/stdc++.h>
using namespace std;

const int N = 100005;  // 定义最大区间数量

int n;  // 区间数量

// 定义区间结构体
struct Range
{
    int l, r;  // 区间的左右端点

    // 重载小于运算符,用于排序
    bool operator< (const Range &W) const
    {
        return l < W.l;  // 按照区间的左端点升序排序
    }
}range[N];  // 定义区间数组

int main()
{
    cin >> n;  // 输入区间数量

    // 输入每个区间的左右端点
    for (int i=0; i<n; i++)
    {
        int l, r;
        cin >> l >> r;
        range[i] = {l, r};  // 将区间存入数组
    }

    sort(range, range+n);  // 按照区间的左端点进行排序

    // 定义一个小根堆,用于存储每组中最后一个区间的右端点
    priority_queue<int, vector<int>, greater<int>> heap;

    // 遍历所有区间
    for (int i=0; i<n; i++)
    {
        auto r = range[i];  // 当前区间

        // 如果堆为空,或者当前区间的左端点小于等于堆顶的右端点
        // 说明当前区间与所有组中的区间都相交,需要新开一个组
        if (heap.empty() || heap.top() >= r.l)
        {
            heap.push(r.r);  // 将当前区间的右端点加入堆
        }
        else
        {
            // 否则,当前区间可以加入堆顶对应的组
            int t = heap.top();  // 取出堆顶的右端点
            heap.pop();         // 弹出堆顶
            heap.push(r.r);      // 将当前区间的右端点加入堆
        }
    }

    // 输出堆的大小,即最少需要的组数
    cout << heap.size() << endl;
    return 0;
}

【运行结果】

3
-1 1
2 4
3 5
2
posted @ 2026-02-27 08:46  团爸讲算法  阅读(1)  评论(0)    收藏  举报