数轴上有n个区间[ai,bi],选择尽量少的区间覆盖一条指定线段[s,t]。
贪心:
把各区间按照a从小到大排序,从前向后遍历,然后每次选择从当前起点S开始的最长区间,并以这个区间的右端点为新的起点,继续选择,直到找不到区间覆盖当前起点S或者S已经到达线段末端。
·
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
struct qu
{
int x;
int h;
double l,r;
} tm[10000+5];
double cmp(qu a,qu b)
{
return a.l<b.l;
}
int main()
{
double t;
cin>>t;
while(t--)
{
int n,w,h;
cin>>n>>w>>h;
int ok=0;
int i,j;
double t1,t2;
for (i=1;i<=n;i++)
{
scanf("%lf %lf",&t1,&t2);
if (t2<h/2)
continue;
tm[++ok].x=t1;
tm[ok].l=t1-sqrt(t2*t2-(h*h*1.0/4.0));
tm[ok].r=t1+sqrt(t2*t2-(h*h*1.0/4.0));
tm[ok].h=t2;
}
sort(tm+1,tm+1+ok,cmp);
int cun=0;
double st=0;
for (i=1;i<=ok&&tm[1].l<=st;i++)
{
double max=0;
for (j=i;tm[j].l<=st&&j<=ok;j++)
{
if (max<tm[j].r)
max=tm[j].r;
}
cun++;
st=max;
if (st>=w)
break;
i=j-1;
}
if (st>=w) cout<<cun<<endl;
else
printf("0\n");
}
return 0;
}