题目:http://codeforces.com/contest/1059/problem/D
题意:给出n个点,要求做一个圆,使得所有点在圆内或圆上,并且该圆与x轴相切。
思路:与y轴相切,那么圆心位置一定在(x,r)上,这道题不需要我们确定圆心位置,那么反着思考,如果该圆包含所有点,那么其他所有点以r作半径的圆一定包含该圆点,然后圆心又在 y=r 这条直线上,我们就可以通过每个点作的圆与这条线交的范围是否存在,判断是否存在这样的圆,r可以用二分查找 时间复杂度(nlog(max))
要注意一下精度,这里用long double 或者勾股定理时先开根号比较稳…
#include<bits/stdc++.h>
#define fi first
#define se second
#define log2(a) log(n)/log(2)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 1e17 + 10;
const int N = 1e6 + 10;
const ll mod = 1e9+7;
const int base=131;
const double pi=acos(-1);
map<string, int>ml;
map<ll,ll> mp;
map<int,int> vi;
priority_queue<P> q;
priority_queue<P> tq;
ll b[N], vis[N], dep[N],num[N], a[N],t, n, m, k;
int ex, ey, cnt, ans, sum, flag;
double x[N],y[N],po[N];
//vector<int> v[N];
vector<int> fac[N];
string s;
map<int,int> dp[N];
char v[1005][1005];
bool check(double R)
{
double l=-1e18,r=1e18,t;
for(int i=1;i<=n;i++)
{
if(y[i]>2*R) return 0;
t=sqrt(R+(R-y[i]))*sqrt(R-(R-y[i]));
l=max(l,x[i]-t);
r=min(r,x[i]+t);
}
return l<=r;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
if(y[i]>0) vis[1]=1;
if(y[i]<0) vis[0]=1;
}
if(vis[1]&&vis[0]) return cout<<-1,0;
if(vis[0])
{
for(int i=1;i<=n;i++) y[i]=-y[i];
}
double l=0,r=1e18,ans,mid;
for(int i=1;i<=500;i++)
{
mid=(l+r)/2.0;
if(check(mid))
{
ans=r=mid;
}
else l=mid;
}
printf("%.10f",ans);
}