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

https://ac.nowcoder.com/acm/contest/3006/B

题目描述

由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标(x,y)

这周末,牛牛队又要出去比赛了,各个比赛的赛点都在x轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。

这个问题对于牛牛战队太简单了,它就交给了你,你来帮他算一下~

思路

题解上写的是三分,二分也可以写,我是二分写的,下面说的就是二分的思路了。

二分这个最小的最大距离,首先这个比赛场地一定在x轴上,对于每个训练基地而言,如果同比赛场地距离为dist,那么比赛场地一定在以它为圆心半径为dist的圆上,即是圆与坐标轴x的两个交点,二分的时候距离小于等于dist即为合法,也就是说只要场地在两个坐标之间即为合法。可以考虑记录这个坐标区间,对于多个训练基地我们求这个坐标区间的交集,如果交集不为空,则这个dist合法,如果交集为空表示这个dist不可行。因为求距离需要开根号,因此还需要特判一下根号下的值是否为正,不是正数直接不合法。

/*************************************************************************
    > File Name: B.cpp
    > Author: amoscykl
    > Mail: [email protected]
    > Created Time: 2020年02月13日 星期四 14时52分21秒
 ************************************************************************/
 
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int inf = 0x3f3f3f3f;
int px[N], py[N];
int n;
#define eps 1e-8
bool check(double x){
    double xl, xr;
    double temp = x * x - py[1] * py[1] * 1.0;
    if (temp < 0)return false;
    temp = sqrt(temp);
    xl = px[1] * 1.0 - temp;
    xr = px[1] * 1.0 + temp;
    for (int i = 2; i <= n; i++){
        temp = x * x - py[i] * py[i] * 1.0;
        if (temp < 0)return false;
        temp = sqrt(temp);
        double txl = px[i] * 1.0 - temp;
        double txr = px[i] * 1.0 + temp;
        if (xl > txr || xr < txl){
            // 没有交集
            return false;
        }
        else{
            xl = max(xl, txl);
            xr = min(xr, txr);
        }
    }
    return true;
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++){
        scanf("%d %d", px + i, py + i);
    }
    double l = 0.0;
    double r = inf * 1.0;
    double res = -1;
    while (r - l > eps){
        double mid = (l + r) / 2.0;
        if (check(mid)){
            res = mid;
            r = mid;
        }
        else l = mid;
    }
    printf("%.6lf\n", res);
    return 0;
}
发布了204 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43701790/article/details/104308735