1. 程式人生 > 其它 >區間合併(貪心)

區間合併(貪心)

給定 n 個區間 [li,ri],要求合併所有有交集的區間。

注意如果在端點處相交,也算有交集。

輸出合併完成後的區間個數。

例如:[1,3] 和 [2,6] 可以合併為一個區間 [1,6]。

輸入格式
第一行包含整數 n。

接下來 n 行,每行包含兩個整數 l 和 r。

輸出格式
共一行,包含一個整數,表示合併區間完成後的區間個數。

資料範圍
1≤n≤100000,
−109≤li≤ri≤109
輸入樣例:
5
1 2
2 4
5 6
7 8
7 9
輸出樣例:
3

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef pair<int, int> PII;
vector<PII> segs;
int n;
void merge(vector<PII> &segs){
    vector<PII> res;//存獨立區間的容器(即答案)
    sort(segs.begin(), segs.end());
    //按區間左端點排序
    //使得每次比較當前維護區間和新區間時,
    //使新區見的左端點肯定大於等於當前維護區間
    //只有兩種情況:
    //即當前維護區間與新區見有交集和無交集
    int st = -2e9,ed = -2e9;//初始區間
    for(auto seg:segs){
        if(ed<seg.first)//沒有交集
            {
                if(st!=-2e9) res.push_back({st,ed});
                st=seg.first,ed=seg.second;
            }
        else//有交集
            ed = max(seg.second,ed);//更新當前維護區間
    }
    if(st!=-2e9) res.push_back({st,ed});
    //若傳入的陣列不為空,將最後一個區間加入答案
    segs=res;
}
int main()
{
    cin>>n;
    while(n--){
        int l,r;
        cin>>l>>r;
        segs.push_back({l,r});
    }
    merge(segs);
    cout<<segs.size()<<endl;
    return 0;
}