#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
struct Range{//利用结构体储存区间
int l, r;
bool operator< (const Range &W) const //按照左端点大小对区间进行排序
{
return l < W.l;
}
}range[N];
int st, ed;
int n;
int main()
{
cin>>st>>ed;
cin>>n;
for(int i = 0; i < n ; i ++ ){
int l, r;
cin>>l>>r;
range[i] = {l, r};
}
sort(range, range + n);//按照左端点对区间进行排序
int res = 0;//储存所需区间个数
bool flag = false;//标记是否能满足题意
for(int i = 0; i < n; i ++ ){//遍历每个区间
int j = i;
int rl = -2e9;//记录当前所用的区间中最靠右的区间的右端点值
while(j < n && range[j].l <= st){//遍历所有能覆盖当前线段头部的区间
rl = max(rl, range[j].r);//记录所有符合条件的区间中最大的右端点
j ++ ;
}
if(rl < st){//如果能利用的区间的最右端都和当前线段的头部没有接触,代表不存在区间能完全覆盖线段,直接退出
break;
}
st = rl;//将当前线段的头部更新为当前利用的区间的最右端,下次直接找和这个端点相交的区间,就能保证区间连续
res ++ ;//区间数量+1
if(st >= ed){//如果线段已被完全覆盖,标记存在这样的一系列连续区间,退出
flag = true;
break;
}
i = j - 1;//双指针算法,让i更新为最新利用的区间的下标,因为for结束会有i ++ ,所以i = j - 1
}
if(!flag) res = -1;//如果不存在符合条件的一系列区间,需输出-1
cout<<res<<endl;
return 0;
}
AcWing 907 区间覆盖 题解 (贪心—区间问题)
最新推荐文章于 2024-08-02 23:27:55 发布