UVALive 4818 - Largest Empty Circle on a Segment (计算几何)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2819

 

题目意思:

给了平面上的n条线段:

让你在x轴上[0,L]的范围内找一个点作为圆心,画一个圆,这个圆不能把线段包含在里面去。

求最大的半径。

 

 

 

求解:

二分最终的答案,求解。

对于二分的半径值,对每条线段找出对于x位置上满足半径要求的段。

看n条线段有没有交集就可以了。

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2014/5/10 23:18:09
  4 File Name     :E:\2014ACM\区域赛练习\2010\2010SouthEastern_European_Region\C.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 
 21 const double eps = 1e-8;
 22 const double inf = 1e5;
 23 const double pi = acos(-1.0);
 24 int sgn(double x)
 25 {
 26     if(fabs(x) < eps)return 0;
 27     else if(x < 0)return -1;
 28     return 1;
 29 }
 30 struct Point
 31 {
 32     double x,y;
 33     Point(){}
 34     Point(double _x,double _y)
 35     {
 36         x = _x;
 37         y = _y;
 38     }
 39     void input()
 40     {
 41         scanf("%lf%lf",&x,&y);
 42     }
 43     Point operator -(const Point &b)const
 44     {
 45         return Point(x-b.x,y-b.y);
 46     }
 47     double operator *(const Point &b)const
 48     {
 49         return x*b.x + y*b.y;
 50     }
 51     double operator ^(const Point &b)const
 52     {
 53         return x*b.y - y*b.x;
 54     }
 55     double len()
 56     {
 57         return hypot(x,y);
 58     }
 59     double distance(Point p)
 60     {
 61         return hypot(x-p.x,y-p.y);
 62     }
 63 };
 64 struct Line
 65 {
 66     Point s,e;
 67     Line(){}
 68     Line(Point _s,Point _e)
 69     {
 70         s = _s;
 71         e = _e;
 72     }
 73     void input()
 74     {
 75         s.input();
 76         e.input();
 77     }
 78     double length()
 79     {
 80         return s.distance(e);
 81     }
 82     double dispointtoline(Point p)
 83     {
 84         return fabs((p-s)^(e-s))/length();
 85     }
 86     double dispointtoseg(Point p)
 87     {
 88         if(sgn((p-s)*(e-s)) < 0 || sgn((p-e)*(s-e)) < 0)
 89             return min(p.distance(s),p.distance(e));
 90         return dispointtoline(p);
 91     }
 92 };
 93 const int MAXN = 2020;
 94 Line line[MAXN];
 95 
 96 double get(int i,double L)
 97 {
 98     double l = 0, r = L;
 99     while(r - l >= eps)
100     {
101         double mid = (l + r)/2;
102         double midmid = (r + mid)/2;
103         if(line[i].dispointtoseg(Point(mid,0)) < line[i].dispointtoseg(Point(midmid,0)))
104             r = midmid - eps;
105         else l = mid + eps;
106     }
107     return l;
108 }
109 int n;
110 double L;
111 
112 struct Node
113 {
114     double a;
115     int c;
116     Node(double _a = 0,int _c = 0)
117     {
118         a = _a;
119         c = _c;
120     }
121 };
122 bool cmp(Node a,Node b)
123 {
124     if(sgn(a.a - b.a) != 0)return a.a < b.a;
125     else return a.c > b.c;
126 }
127 
128 double bin1(int i,double l,double r,double R)
129 {
130     while(r-l >= eps)
131     {
132         double mid = (l+r)/2;
133         if(line[i].dispointtoseg(Point(mid,0)) <= R)
134             r = mid - eps;
135         else l = mid + eps;
136     }
137     return l;
138 }
139 double bin2(int i,double l,double r,double R)
140 {
141     while(r-l >= eps)
142     {
143         double mid = (l+r)/2;
144         if(line[i].dispointtoseg(Point(mid,0)) <= R)
145             l = mid + eps;
146         else r = mid - eps;
147     }
148     return l;
149 }
150 
151 bool gao(double r)
152 {
153     vector<Node>vec;
154     for(int i = 0;i < n;i++)
155     {
156         double tmp = get(i,L);
157         if(sgn(line[i].dispointtoseg(Point(tmp,0)) - r) >= 0)
158         {
159             vec.push_back(Node(0,1));
160             vec.push_back(Node(L,-1));
161             continue;
162         }
163         if(sgn(line[i].dispointtoseg(Point(0,0)) - r) >= 0)
164         {
165             double tt = bin1(i,0,tmp,r);
166             vec.push_back(Node(0,1));
167             vec.push_back(Node(tt,-1));
168         }
169         if(sgn(line[i].dispointtoseg(Point(L,0)) - r) >= 0)
170         {
171             double tt = bin2(i,tmp,L,r);
172             vec.push_back(Node(tt,1));
173             vec.push_back(Node(L,-1));
174         }
175     }
176     sort(vec.begin(),vec.end(),cmp);
177     int cnt = 0;
178     for(int i = 0;i < vec.size();i++)
179     {
180         cnt += vec[i].c;
181         if(cnt >= n)return true;
182     }
183     return false;
184 }
185 
186 double solve()
187 {
188     double l = 0, r = inf;
189     while(r-l >= eps)
190     {
191         double mid = (l+r)/2;
192         if(gao(mid))l = mid+eps;
193         else r = mid - eps;
194     }
195     return l;
196 }
197 
198 int main()
199 {
200     //freopen("in.txt","r",stdin);
201     //freopen("out.txt","w",stdout);
202     int T;
203     scanf("%d",&T);
204     while(T--)
205     {
206         scanf("%d%lf",&n,&L);
207         for(int i = 0;i < n;i++)
208             line[i].input();
209         printf("%.3lf\n",solve());
210     }
211     return 0;
212 }

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2014-05-11 21:45  kuangbin  阅读(1088)  评论(0编辑  收藏  举报

导航

JAVASCRIPT: