codeforce #514 D. Nature Reserve

D. Nature Reserve
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
There is a forest that we model as a plane and live nn rare animals. Animal number ii has its lair in the point (xi,yi)(xi,yi). In order to protect them, a decision to build a nature reserve has been made.
The reserve must have a form of a circle containing all lairs. There is also a straight river flowing through the forest. All animals drink from this river, therefore it must have at least one common point with the reserve. On the other hand, ships constantly sail along the river, so the reserve must not have more than one common point with the river.
For convenience, scientists have made a transformation of coordinates so that the river is defined by y=0y=0. Check whether it is possible to build a reserve, and if possible, find the minimum possible radius of such a reserve.
Input
The first line contains one integer nn (1≤n≤1051≤n≤105) — the number of animals.
Each of the next nn lines contains two integers xixi, yiyi (?107≤xi,yi≤107?107≤xi,yi≤107) — the coordinates of the ii-th animal's lair. It is guaranteed that yi≠0yi≠0. No two lairs coincide.
Output
If the reserve cannot be built, print ?1?1. Otherwise print the minimum radius. Your answer will be accepted if absolute or relative error does not exceed 10?610?6.
Formally, let your answer be aa, and the jury's answer be bb. Your answer is considered correct if |a?b|max(1,|b|)≤10?6|a?b|max(1,|b|)≤10?6.
Examples
input
Copy

1 0 1

output
Copy
0.5

input
Copy
3 0 1 0 2 0 -3

output
Copy
-1

input
Copy
2 0 1 1 1

output
Copy
0.625

Note
In the first sample it is optimal to build the reserve with the radius equal to 0.50.5 and the center in (0, 0.5)(0, 0.5).
In the second sample it is impossible to build a reserve.
【codeforce #514 D. Nature Reserve】In the third sample it is optimal to build the reserve with the radius equal to 5858 and the center in (12, 58)(12, 58).

题意:给出n个点,找到一个圆,使得这个圆的半径最小,并且与X轴相切,并且包含n个点
思路:
1.二分找半径r,那么我们要判断r是否合法,那么可以根据已给出的r求出每个圆圆心的x的坐标区间(y坐标永远是R),那么只要所有的点的圆的x的区间至少有一个交点,那么当前的r是合法的,那么减小r的取值,如果不合法,那么说明给的R太小了,把R变大即可
#include #include #include #include #define maxn 100001 +10 #define INF 0xfffffff using namespace std; int n; struct node{ double x,y; }a[maxn]; int check(long double r) { int i; double l=-100000000000000000.0; double rig=100000000000000000.0; for(i=0; ir+r) { return 0; } if(r*r-(a[i].y-r)*(a[i].y-r)<0) return 1; double left=a[i].x-sqrt(2*a[i].y*r-a[i].y*a[i].y); double right=a[i].x+sqrt(2*a[i].y*r-a[i].y*a[i].y); l=max(left,l); rig=min(right,rig); } return l0&&z>0) { printf("-1\n"); continue; } double left=0.0; double right=100000000000000000.0; double mid=(left+right)*1.0/2; //printf("%.10Lf\n",right); int cnt=0; while(cnt<301) { cnt++; //printf("%lf\n",mid); if(check(mid)) { right=mid; } else { left=mid; } mid=(right+left)/2.0; } printf("%lf\n",mid); } return 0; }


    推荐阅读