AcWing 907 区间覆盖 题解 (贪心—区间问题)

#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; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值