思路
【假设非覆盖区间是[start,tail]
】
第一步:对所有区间的左端点排序
第二步:枚举所有区间。对于剩余未覆盖部分,每次找到能够覆盖最多的区间seg(区间能覆盖住左端点,且延伸最远,覆盖最多),并更新start(更新剩余未覆盖部分)。由于区间是按照左端点排序的,故寻找seg时不用每次都枚举所有区间。
C++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
const int N = 1e5+10;
int n,start,tail;
PII q[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>start>>tail>>n;
for(int i=0;i<n;i++) cin>>q[i].first>>q[i].second;
sort(q, q + n); //按左端点排序
int res = 0, max_r = -2e9;
bool success = false; //是否覆盖成功
//从第一个区间开始枚举,每次找到覆盖最多的区间(能覆盖左端点,且右端点延伸最远)
int i = 0;
while(1)
{
while(i < n && q[i].first <= start)
{
if(q[i].second > max_r)
max_r = q[i].second;
i++;
}
if(max_r <= start)
break; //无法完全覆盖
res++; //区间+1
start = max_r; //更新start
if(start >= tail) //如果所有部分都已覆盖,success!
{
success = true;
break;
}
}
if(success) cout<<res<<endl;
else puts("-1");
return 0;
}