2020牛客寒假算法基础集训营5 B.牛牛战队的比赛地

2020牛客寒假算法基础集训营5 B.牛牛战队的比赛地

题目描述

由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标(x,y)。
这周末,牛牛队又要出去比赛了,各个比赛的赛点都在xx轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。
这个问题对于牛牛战队太简单了,它就交给了你,你来帮他算一下~

输入描述:

输入数据第一行包含一个整数 N ( 1 N 100 000 ) N(1 \leq N \leq 100\,000) ,表示牛牛战队训练基地的数量。

接下来N行,每行包括2个整数 x , y ( 10 000 x , y 10 000 ) x,y(-10\,000 \leq x,y \leq 10\,000) ,表示每一个训练基地的坐标。

输出描述:

输出一个小数,表示选择的比赛地距离各训练基地最大距离的最小值。

如果你的答案是a,标准答案是b,当 a b m a x ( 1 , b ) 1 0 4 \frac{|a-b|}{max(1,|b|)}\leq 10^{-4} 时,你的答案将被判定为正确。

示例1

输入

3
0 0
2 0
0 2

输出

2

看了题解补了一下题,用的三分查找,我比赛时一直怀疑二分查找的准确性,但其实不难发现,目标答案一定是收敛的,注意三分的判别条件不能用 l < r l<r ,因为精度问题会导致超时,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;
}
发布了288 篇原创文章 · 获赞 14 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43765333/article/details/104308825