区间覆盖

该博客介绍了一种算法,通过排序区间并逐步选择右端点最大的区间来覆盖指定线段的方法。首先按区间左端点升序排序,然后枚举每个区间,找到能覆盖指定起点且右端点最大的区间,更新起点并计数,直到覆盖完整个线段。代码展示了具体的实现过程。

要覆盖[start , end]这个区间

问题描述

数轴上有n个闭区间[ai,bi],选择尽量少的区间覆盖一条指定的线段[s,t]

做法

①将所有区间 按左端点 从小到大排序
②从前往后一次枚举每个区间,在所有能覆盖shart的区间中,选择右端点最大的区间,然后将start更新成右端点的最大值。

代码

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 100010;
int n;

struct NODE
{
	int Left;
	int Right;	
}node[N];

bool Cmp(NODE &a, NODE &b)
{
	return a.Left<b.Left;	
} 

int main(int argc, char** argv) 
{
	//读入要覆盖的区间 
	int Start,End;
	scanf("%d%d",&Start, &End);
	
	//读入区间总数 
	scanf("%d", &n);
	
	for(int i = 0; i < n; i++)
	{
		scanf("%d%d", &node[i].Left, &node[i].Right);
	}
	
	//按左端点从小打到排序 
	sort(node, node+n, Cmp);
	
	//要用几个区间覆盖掉整个Start End 
	int Cnt = 0;
	bool IsSuccess = false;
	
	for(int i = 0; i < n; i++)
	{
		int j = i;
		//MaxRight保存能覆盖Start 且 右端点最大的那个 
		int MaxRight = -2e9;
		
		//保证不越界 而且可以被覆盖掉 
		while(j < n && node[j].Left <= Start)
		{
			MaxRight = max(MaxRight,node[j].Right);
			j++;
		}
		
		//说明没有区间不能覆盖此区间的Start 
		if(j == i)
		{
			break;
		}
		
		//又用了一个区间 
		Cnt++;
		//整个区间已经完全被覆盖了 
		if(MaxRight >= End)
		{
			IsSuccess = true;
			break;
		}
		//更新区间 
		Start = MaxRight;
		//j之前的区间不可能再去覆盖Start了 因为MaxRight是j 
		i = j-1; 
	}
	
	if(IsSuccess)
	{
		cout<<Cnt<<endl;
	}
	else
	{
		cout<<"-1"<<endl;
	}
	return 0;
}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值