题目大意:输入n,l,w.分别代表有n个喷水装置,草地长为L,宽为W;接下来n行,每行两个数,a,r,分别代表喷水装置在草地中的横坐标,和喷水半径。喷水装置的纵坐标都是草地的正中央。求用最少的喷水装置洒水,覆盖所有的草地,若不能输出-1,能则输出所需的最少的喷水装置数目。
题目解析:排序+贪心,恶心的是卡了精度!输入时计算出所有喷水装置能覆盖的横坐标的范围。已知圆的半径和弦长,则可以求出圆心到弦长的距离s,用圆心的位置a-s则可得当前喷水装置能覆盖的最左边的的草地,a+s,表示能覆盖的最右边的草地坐标。然后以最左边的覆盖范围为依据排序,然后贪心满足条件的能覆盖到最右边的喷水装置。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MAX 100010
typedef struct node
{
double L,R;
}node;
node map[MAX];
const double INF=10e-9;
int n,l,w;
int cmp(const void *aa,const void *bb)
{
node *a=(node *)aa;
node *b=(node *)bb;
if (a->L!=b->L)
return a->L > b->L ?1:-1;
return a->R > b->R ?1:-1;
}
int main()
{
while (scanf("%d%d%d",&n,&l,&w)!=EOF)
{
int i,j=0,a,r,m=0;
double ans,cnt;
for (i=0;i<n;i++)
{
scanf("%d%d",&a,&r);
if (r*2>w)
{
ans=sqrt((double)r*r-(double)w*w/4.0);
map[j].L=(double)a-ans;
map[j++].R=(double)a+ans;
}
}
qsort(map,j,sizeof(node),cmp);
cnt=ans=0.0;
for (i=0;i<j;i++)
{
int flag=0,tot=0;
cnt=ans;
while (map[i].L-cnt<INF&&i<j)
{
if (map[i].R>ans)
{
ans=map[i].R;
tot=1;
}
i++;
flag=1;
}
if (flag)
{
i--;
}
if (tot)
m++;
if (ans>l)
break;
}
if (ans>=l)
printf("%d\n",m);
else
printf("-1\n");
}
return 0;
}