问题:
数轴上有 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
sample input:
3 10
1 7
3 6
6 10
sample output:
2
题解:
这个题与区间选点问题大同小异,我们还是需要将区间进行排序,不过是先按左端点升序,再按照右端点升序,这样就可以保证我们区间是有序的。
之后我们从第一个区间开始,首先判断是否在一的右边,不在的话就开始循环,我们使用一个nowl,nowr记录现在选出的区间的范围。如果这个区间的左端点值小于nowl,右端点值小于的话没有意义,右端点值大于的话,就说明该区间覆盖了我们之间选择的区间,更新选择的区间的。如果这个区间的左端点大于我们选择的左端点,并且右端点大于我们选择的右端点,那么说明我们应该选择一个新的区间,并且如果左端点大于我们选择的右端点+1,说明不能覆盖。这样重复知道循环结束,或者已经覆盖要覆盖的区域。
完整代码:
#include <iostream>
#include <list>
#include <cstring>
#include <stdio.h>
#include <algorithm>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct qu{
int r;
int l;
};
bool compare(qu &x,qu &y) //新的比较函数
{
if(x.l==y.l)
{
return x.r<y.r;
}
else
{
return x.l<y.l;
}
}
int main(int argc, char** argv) {
int n;
int count=1;
cin>>n;
qu* jian=new qu[n];
int t;
cin>>t;
bool is=true;
for(int i=0;i<n;i++)
{
scanf("%d",&jian[i].l);
scanf("%d",&jian[i].r);
}
sort(jian,jian+n,compare);
int nowl=1;
int nowr=1;
if(jian[0].l>1)
{
is=false;
}
else
{
for(int i=0;i<n;i++)
{
if(jian[i].l<=nowl)
{
if(jian[i].r>nowr) nowr=jian[i].r;
}
else
{
if(jian[i].r>nowr)
{
if(jian[i].l>nowr+1)
{
is=false;
break;
}
count++;
nowl=nowr+1;
nowr=jian[i].r;
}
}
if(nowr>=t)
{
break;
}
}
}
if(nowr>=t&&is)
{
cout<<count<<endl;
}
else
{
cout<<-1<<endl;
}
return 0;
}