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 }
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想