牛牛战队的比赛地

传送门:https://ac.nowcoder.com/acm/contest/3006/B

题意:

  在二维坐标系有n个点,要求要在x轴正负一万内找到一个点,使这个点到那n个点的最大距离最小。

思路:

  设在x上的最大距离为fun(x),也就是存在一个点,它的左边fun比他小,右边的fun也比它小,所以这个点在区间内就是个最小值,我们就可以用到三分搜索查询最小值,直接套模板就行了。

  这题还可以二分做,怎么做呢?其实思想是一样的,目的都是求极小值,求出一个mid之后看mid左边和mid右边哪个小,答案就在小的那边舍弃另一边继续迭代即可。

ac代码

#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
const int maxn=1e5+5;
const double eps=1e-6;
int n;
struct node{
    int x,y;
}a[maxn];

double fun(double x){
    double maxx=-1,tmp;
    for(int i=1;i<=n;i++){
        tmp=sqrt(1.0*a[i].y*a[i].y+(a[i].x-x)*(a[i].x-x));
        if(tmp>maxx) maxx=tmp;
    }
    return maxx;
} 

double ssearch(double l,double r){
    double mid,midmid;
    while(l+eps<=r){
        mid=(l+r)/2;
        midmid=(mid+r)/2;
        if(fun(mid)>fun(midmid))
            l=mid;
        else
            r=midmid;
    }
    return fun(l); 
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i].x>>a[i].y;
    }
    double ans=ssearch(-10000,10000);
    printf("%.5f",ans);
    return 0;
}
三分
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
const int maxn=1e5+5;
const double eps=1e-6;
int n;
struct node{
    int x,y;
}a[maxn];

double fun(double x){
    double maxx=-1,tmp;
    for(int i=1;i<=n;i++){
        tmp=sqrt(1.0*a[i].y*a[i].y+(a[i].x-x)*(a[i].x-x));
        if(tmp>maxx) maxx=tmp;
    }
    return maxx;
} 

double ssearch(double l,double r){
    double mid,midmid;
    while(l+eps<=r){
        mid=(l+r)/2;
        if(fun(mid+eps)<fun(mid-eps))
            l=mid;
        else
            r=mid;
    }
    return fun(l); 
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i].x>>a[i].y;
    }
    double ans=ssearch(-10000,10000);
    printf("%.5f",ans);
    return 0;
}
二分

 

 

  

posted @ 2020-03-23 19:14  艾尔夏尔-Layton  阅读(168)  评论(0编辑  收藏  举报