Nature Reserve

Nature Reserve
time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output
Problem Description

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). 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=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 n (1≤n≤1e5) — the number of animals.

Each of the next n lines contains two integers xi, yi (−1e7≤xi,yi≤1e7) — the coordinates of the i-th animal's lair. It is guaranteed that yi≠0. No two lairs coincide.

Output

If the reserve cannot be built, print −1. Otherwise print the minimum radius. Your answer will be accepted if absolute or relative error does not exceed 1e−6.

Formally, let your answer be aa, and the jury's answer be bb. Your answer is considered correct if |ab| / max(1,|b|)1e6.

Examples
input
1
0 1
output
0.5
input
3
0 1
0 2
0 -3
output
-1
input
2
0 1
1 1
output
0.625
Note

In the first sample it is optimal to build the reserve with the radius equal to 0.5 and the center in (0, 0.5).

In the second sample it is impossible to build a reserve.

In the third sample it is optimal to build the reserve with the radius equal to 5/8 and the center in (1/2, 5/8).

题目链接:http://codeforces.com/contest/1059/problem/D


题意:有二维平面上n个点,能否找到一个半径最小的与x轴相切的圆,覆盖全部的点。

分析:首先二分答案,则题目转化为判断半径为定值的与x轴相切的圆能否覆盖全部的点。如果点在x轴上下都有分布,则找不到这样的圆。然后发现既然圆的半径为定值且与x轴相切,则它的圆心是在一条直线上,然后这个圆要覆盖某个点,则以这个点为圆心,半径为r的圆一定也能覆盖这个圆心。再推广发现圆心的那条直线上只有一段区间满足能覆盖该点。于是把全部的点在直线上对应的区间求出来,求出区间交集即可判断这样的圆是否存在。

官方题解:http://codeforces.com/blog/entry/62238

#include<bits/stdc++.h>
#define N 105000
const double INF =1e18;
using namespace std;
struct ss
{
    double x,y;
};
ss arr[N];
int n;

int check(double r)
{
    double cross_l=-INF,cross_r=INF;
    
    for(int i=1;i<=n;i++)
    {
        if(arr[i].y>2*r)return 0;
        
        double dis=sqrt(arr[i].y*r*2.0-arr[i].y*arr[i].y);
        double nowl=arr[i].x-dis,nowr=arr[i].x+dis;

        cross_l=max(cross_l,nowl);
        cross_r=min(cross_r,nowr);
        if(cross_l>cross_r)return 0;
    }
    return 1;
}

int main()
{
    double t;
    scanf("%d",&n);
    scanf("%lf %lf",&arr[1].x,&arr[1].y);
    
    if(arr[1].y>0)t=1;
    else
    t=-1;
    arr[1].y*=t;

    for(int i=2;i<=n;i++)
    {
        scanf("%lf %lf",&arr[i].x,&arr[i].y);
        if(arr[i].y*t<0)
        {
            printf("-1\n");
            return 0;
        }
        arr[i].y*=t;
    }
    
    double l=0,r=INF;
    double ans;

    int tot=150;
    while(l<r&&tot--)
    {
        double mid=(l+r)/2;
        if(check(mid))
        {
            ans=mid-1e-7;
            r=mid;
        }
        else
        l=mid+1e-7;
    }
    printf("%f",ans);
    return 0;
}
View Code

 

posted @ 2018-10-07 22:47  1371767389  阅读(796)  评论(0编辑  收藏  举报