区间分组详解
步骤
按照左端点排序原因(个人理解):让每个组的区间都排列的更加紧密,并且如果按照右端点排序,而不知道左端点的位置,可能造成误差
priority_queue<int>表示一个大根堆,队列的顶部存储的是最大的元素。
priority_queue<int, std::vector<int>, std::greater<int>>表示一个小根堆,队列的顶部存储的是最小的元素。
判断是否需要添加一个新组
if (heap.empty() || heap.top() >= r.l) heap.push(r.r);//堆是空的或者堆顶的值大于该区间的左端点,需要开一个新组else{heap.pop();//删掉堆顶heap.push(r.r);//把当前的新的右端点加入堆}
堆中存放的是所有组的最大右端点,每次比较新区间和所有组最大右端点中的最小进行比较,因为新区间左端点如果比最小值还要小的话那肯定和其他组的也重合了,就要开新组,如果比最小值大,那一定可以加入最小值那个组,也就不用比较其他组了
AC代码
#include <iostream>
#include <algorithm>
#include <queue>using namespace std;const int N = 100010;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{heap.pop();//删掉堆顶heap.push(r.r);//把当前的新的右端点加入堆}}cout<<heap.size();//堆的大小就是组的个数return 0;
}