1.题意
数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]
( 1<=t<=1,000,000)。
覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
不可能办到输出-1
2.样例
Input
第一行:N和T
第二行至N+1行: 每一行一个闭区间。
Output
选择的区间的数目,不可能办到输出-1
Sample Input
3 10
1 7
3 6
6 10
Sample Output
2
3.解题思路
分析:
贪心策略:相同起点以覆盖长度最长,即以a降序,b升序排列。
要先检验是否有区间的起点在要覆盖的区间起点上,更新分为最初起点1和新更新起点,通过判断覆盖的区间长度是否符合要覆盖的区间长度如果在循环中间断掉则说明不可能达到如果没有起点或终点为1的区间也不可能达到
4.总结
1.该题只要求覆盖整点,在比较区间的起点是s1和更新的覆盖起点s2时条件为s1<=s2+1;
2.由于本题用的覆盖长度判断所以当t=1时并没有进入循环所以要特判;
3.同时在1中,起点为1时的判断条件无需加一,因为要保证有区间起点为1
4.若输入多组数据时,max应在while内每次置零,且max==0时输出-1后应为break而非return且vector要清空;
5.AC代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct point{
int x;
int y;
bool operator < (const point &p)const
{
return x !=p.x ? x<p.x : p.y<y;
}
};
int main()
{
int n,t,a,b;
vector<point> v;
scanf("%d%d",&n,&t);
int count=0;
bool judge=true,ju=true;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
point t1;
t1.x=a;
t1.y=b;
v.push_back(t1);
}
sort(v.begin(),v.end());
int q=1;
int len=0,j;
while(len<t-1)
{
int max=0;
for(int i=0;i<v.size();i++)
{
point te=v[i];
if(te.x<=(q+1)&&q>1)
{
if(te.y-q>max)
{
max=te.y-q;
j=i;
}
}
else if(te.x<=q&&q==1)
{
if(te.y-q>max)
{
max=te.y-q;
j=i;
}
}
else break;
}
if(max==0)
{
cout<<"-1"<<endl;
judge=false;
break;
}
len=len+max;
count++;
q=v[j].y;
}
if(t==1)
{
for(int i=0;i<v.size();i++)
{
if(v[i].x==1||v[i].y==1)
{
ju=false;
}
}
if(ju==false) cout<<"1"<<endl;
if(ju==true) cout<<"-1"<<endl;
}
if(judge==true&&t!=1) cout<<count<<endl;
while(v.size()!=0)
{
v.pop_back();
}
return 0;
}