UVA 10382喷水设施

UVA 10382

【题目描述】:喷水设置

有一块草坪,长为l,宽为w,在草坪的中心线上,放置规格不一的喷水装置,给定每个装置的安置中心,辐射半径(pos,rad)。求最少几个喷水装置可以辐射整块草坪?

【算法分析】:

把二维退化到一维问题,我们要考虑的辐射边界,pos+(-)sqrt(rad^2-w^2/4),想象一下,如果边界辐射到了,中间一定辐射到了,若rad<w/2的话,是不起作用的,要丢弃。

现在的模型,给定多条线段的,坐标表示(l,r),现在要让这个线段覆盖[0,l]这段范围。用贪心策略,设置当前覆盖的位置np,每次选择一条左端点在np的左边(或包括),右端面最靠右的,贪心模拟即可。为了减少每次选择的复杂度,预先排序即可。

【注意】:但是最坑的是eps啊,一定要注意做差和大小写符号。不然一直W。= =

//深坑,这道题的坑不在于算法,而是eps的处理啊,超时和W的血泪史,eps写不好不仅会W

//更坑的是超时啊

【完整代码】:

  1 #include<iostream>
  2 
  3 #include<stdio.h>
  4 
  5 #include<string.h>
  6 
  7 #include<algorithm>
  8 
  9 #include<stdlib.h>
 10 
 11 #include<math.h>
 12 
 13 #include<queue>
 14 
 15 #include<vector>
 16 
 17 #include<map>
 18 
 19 #define MAXN 10000+5
 20 
 21 #define MAXM 50+5
 22 
 23 #define oo 95565354451
 24 
 25 #define eps 0.000001
 26 
 27 #define PI acos(-1.0)//这个精确度高一些
 28 
 29 #define REP1(i,n) for(int i=0;i<(n);i++)
 30 
 31 #define REP2(i,n) for(int i=1;i<=(n);i++)
 32 
 33 using namespace std;
 34 
 35  
 36 
 37 int n;
 38 
 39 double l,w;
 40 
 41 int cnt;
 42 
 43 struct Line
 44 
 45 {
 46 
 47     double x;
 48 
 49     double y;
 50 
 51     bool operator <(const Line& l) const
 52 
 53     {
 54 
 55         return x<l.x;
 56 
 57     }
 58 
 59 } line[MAXN];
 60 
 61  
 62 
 63 void RandB()
 64 
 65 {
 66 
 67     cnt=0;
 68 
 69     for(int i=0; i<n; i++)
 70 
 71     {
 72 
 73         double pos,rad;
 74 
 75         scanf("%lf%lf",&pos,&rad);
 76 
 77         if (rad<w/2) continue;
 78 
 79         double sq=sqrt(rad*rad-(w*w)/4);
 80 
 81         double x=pos-sq,y=pos+sq;
 82 
 83         if (x>=l || y<=0) continue;
 84 
 85         line[cnt].x=pos-sq;
 86 
 87         line[cnt++].y=pos+sq;
 88 
 89     }
 90 
 91     sort(line,line+cnt);
 92 
 93 }
 94 
 95 int solve()
 96 
 97 {
 98 
 99     double Npos=0;//当前坐标
100 
101     int p=0;//指针,指向line
102 
103     int ans=0;
104 
105     if (line[0].x>eps || cnt==0) return -1;
106 
107     else
108 
109     {
110 
111         while(l-Npos>eps && p<cnt)
112 
113         {
114 
115             if (line[p].x-Npos>=eps) break;
116 
117             double most=Npos;//找到最远的y
118 
119             while(line[p].x-Npos<=eps && p<cnt)
120 
121             {
122 
123                 most=max(most,line[p].y);    //x在Npos的左边,贪心去y最大的
124 
125                 p++;
126 
127             }
128 
129             ans++;
130 
131             Npos=most;
132 
133         }
134 
135     }
136 
137     if (l-Npos>=eps) return -1;
138 
139     else  return ans;
140 
141 }
142 
143 int main()
144 
145 {
146 
147     while(~scanf("%d%lf%lf",&n,&l,&w))
148 
149     {
150 
151         RandB();
152 
153         printf("%d\n",solve());
154 
155     }
156 
157     return 0;
158 
159 }

 

 

 【关键词】:降维,eps处理
posted @ 2014-01-18 17:07  little_w  阅读(228)  评论(0编辑  收藏  举报