AcWing 803. 区间合并

题目传送门

一、理解与感悟

  1. \(PII\)记录区间。
  2. 排序,默认排序按左端点排序。
  3. 由左到右遍历每个区间,如果发生间隔,就将已经确定的区间入结果集。
  4. 如果发生相交或内置,则看谁管的远,就将截止点设置成谁。
  5. 什么时间往结果里放入?现在模板的逻辑是本区间与下一个区间存在空隙时,将本区间放入结果,这样就有一个漏洞,就是:最后一个因为找不到下一个区间,导致没有被放入结果。所以,别忘了最后一个区间也要手动添加到结果集。

二、代码模板

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> PII;

//线段数组
vector<PII> segs;
//结果数组
vector<PII> res;

/**
 * 功能:区间合并
 */
void merge() {
    //如果区间为空,那还合并个头啊
    if (segs.size() == 0) return;
    //区间合并,必须先排序,PII排序,C++中默认是按第一个int排序的,即左边界
    sort(segs.begin(), segs.end());
    //初始化st=第一个区间的左边界,ed=第一个区间的右边界
    int st = segs[0].first, ed = segs[0].second;
    //从第二个开始进行叠加
    for (int i = 1; i < segs.size(); i++)
        if (ed < segs[i].first) {
            //如果后面的与前面的中间存在间隔,那么需要把先面的入结果集,后面是独立的存在
            res.push_back({st, ed});
            //初始新的区间开始和结束
            st = segs[i].first, ed = segs[i].second;
        }//如果存在交集,那么取谁管的远听谁的
        else ed = max(ed, segs[i].second);
    //将最后一个区间记录到结果集中
    res.push_back({st, ed});
}


int main() {
    //优化输入
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    //读入数据
    for (int i = 1; i <= n; i++) {
        int l, r;
        cin >> l >> r;
        segs.push_back({l, r});
    }
    //合并区间
    merge();
    //输出结果
    cout << res.size() << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/littlehb/p/15242447.html