传送门: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; }