uva10382 - Watering Grass

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章