2020牛客寒假算法基础集训营5 B.牛牛战队的比赛地
题目描述
由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标(x,y)。
这周末,牛牛队又要出去比赛了,各个比赛的赛点都在xx轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。
这个问题对于牛牛战队太简单了,它就交给了你,你来帮他算一下~
输入描述:
输入数据第一行包含一个整数 ,表示牛牛战队训练基地的数量。
接下来N行,每行包括2个整数 ,表示每一个训练基地的坐标。
输出描述:
输出一个小数,表示选择的比赛地距离各训练基地最大距离的最小值。
如果你的答案是a,标准答案是b,当 时,你的答案将被判定为正确。
示例1
输入
3
0 0
2 0
0 2
输出
2
看了题解补了一下题,用的三分查找,我比赛时一直怀疑二分查找的准确性,但其实不难发现,目标答案一定是收敛的,注意三分的判别条件不能用 ,因为精度问题会导致超时,AC代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
double eps=1e-8;
const int N=1e5+5;
int n;
struct point{
double x,y;
}p[N];
double Distance(point p1,point p2){
return (sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
}
double check(double x){
double ans=0;
point P;
P.x=x,P.y=0;
for(int i=0;i<n;i++){
ans=max(ans,Distance(P,p[i]));
}
return ans;
}
double tsearch(double left,double right){
double mid1,mid2;
while(right-left>eps){
mid1=left+(right-left)/2;
mid2=mid1+(right-mid1)/2;
if(check(mid1)>check(mid2))
left=mid1;
else
right=mid2;
}
return mid1;
}
int main() {
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
double ans=tsearch(-10000,10000);
printf("%.4f",check(ans));
return 0;
}