一个数字段由首尾两个数字标识,表示一个自然数集合,比如数字段[beg, end)表示从beg到end之间的所有自然数,包含beg,但不包含end。

有若干个数字段,这些数字段之间可能有重叠,
怎么把这些数字段合并去重,用最少个数的数字段来表示。
合并前后,整个集合包含的数字不发生变化。

输入描述:

第一行为数字N,表示接下来有N个数字段(N<=100000)
第二行开始一共有N行,每行两个数字,分别表示一个数字段的beg和end
(beg和end为无符号32位整数)

输出描述:

合并去重后形成的数字段集合,按升序排列。

示例1
输入
4 
3 8
3 7
4 6
7 9
输出
3 9

解题:

对数据进行排序,按照first从小到大,first相等时second从小到大,
这样,只需要判断前一个区间的second与后一个区间的first之间的关系即可。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
using Pair = pair<int,int>;

bool comp(Pair a, Pair b){
    return (a.first!=b.first)?(a.first<b.first):(a.second<=b.second);
}
vector<Pair> v;
vector<Pair> ans;

int main(){
    int n,x,y;
    cin>>n;
    while(n--){
        cin>>x>>y;
        v.push_back(make_pair(x,y));
    }
    sort(v.begin(), v.end(), comp);
    int k=-1;
    for(auto i : v){
        if(k>=0 && i.first<=ans[k].second)
            ans[k].second=max(i.second,ans[k].second);
        else{
            ans.push_back(i);
            k++;
        }
    }
    for(auto i : ans)
        cout<<i.first<<' '<<i.second<<endl;

    return 0;   
}