问题描述
数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
不可能办到输出-1
Input
第一行:N和T
第二行至N+1行: 每一行一个闭区间。
Output
选择的区间的数目,不可能办到输出-1
Example
Input |
---|
3 10
1 7
3 6
6 10
Output |
---|
2
问题分析
这道题输入数据很多,请用scanf而不是cin(scanf比cin快一丢丢)。注意题目中的要求:覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。题目解法是使用贪心算法:预处理:[s, t] 之外的部分切掉,相互包含:不考虑小区间。按 a 从小到大排序,区间 1 的起点不是 s,无解;否则选择起点在 s 的最长区间。选择区间 [ai, bi] 后的起点应设置为 bi,并切掉 bi 之前的部分。
其实区间覆盖和区间选点有异曲同工之妙,区间+贪心。下面是区间选点的连接,大家可以做一下类比学习:区间选点https://blog.csdn.net/YingMila/article/details/104781398
最后不得不说一句贪心大法好!
#include<stdio.h>
#include<algorithm>
using namespace std;
struct TT
{
int x,y;
};
bool cmp(TT a,TT b)
{
return a.x<b.x;
}
int main()
{
int n,ans=0,T,S=1,a0=0,S1=1;
TT a[25005];
scanf("%d%d",&n,&T);
for(int i=0;i<n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
sort(a,a+n,cmp);
while(S<=T)
{
while(a0<n && a[a0].x<=S)
{
if(S1<a[a0].y+1)
S1=a[a0].y+1;
a0++;
}
if(S==S1)
{
ans=-1;
break;
}
else ans++;
S=S1;
}
printf("%d",ans);
return 0;
}