题意:
多组数据,每组数据给出n,表示n个点的坐标,然后从x轴上选择一点,使得所有点到该点的最大值最小,并输出该点在x轴上的位置和所有点到该点的最大值
题解:
很明显
d
i
s
(
x
i
)
=
m
a
x
(
(
x
i
−
x
)
2
+
(
y
i
−
y
)
2
)
dis(x_i)=max((x_i-x)^2+(y_i-y)^2)
dis(xi)=max((xi−x)2+(yi−y)2),要求min_dis,容易看出是一个关于x的下凹函数,所以直接三分即可,很模板的一道题
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
#define LL long long
const int MAXN = 50000+50;
const int MAXM = 2e5+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
int n; double x[MAXN],y[MAXN];
inline double dis(double x,double y,double xx,double yy){
return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
}
inline double check(double xx){
double res=0.0;
for(int i=1;i<=n;i++) res=max(res,dis(x[i],y[i],xx,0));
return res;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(~scanf("%d",&n) && n){
for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]);
double l=-200000.0,r=200000.0;
while(r-l>1e-9){
double mid1=(l*2+r)/3,mid2=(l+r*2)/3;
if(check(mid1)<check(mid2)) r=mid2;
else l=mid1;
}
double res=0.0;
for(int i=1;i<=n;i++) res=max(res,dis(x[i],y[i],l,0));
printf("%.9f %.9f\n",l,res);
}
return 0;
}