題目大意:輸入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;
}