【三分查找求单峰函数的最值】 ZOJ 3386 Trick or Treat

         题目大意是:在一个平面上有N个点,每个点的坐标已经给出,现在要求在X轴上找一个点,使得这个点到所有点中最大的距离最小。

         分析:我们设这个点为X0,所求的距离为F(x),那么对于所有的 X < X0 和 X > X0 都有F(x) > ans,即实际上这个函数是已X0为最小值,两边

都是单调递增或者递减的,因此我们可以三分查找找出这个最值的坐标。总复杂度O(n*logn).

         PS:这是第一次写三分,之前竟然从没写过Orz...

#include <cstdio> #include <cstring> #include <cmath> #define INF 1e60 #define EPS 1e-6 #define MAXN 50010 using namespace std; double x[MAXN],y[MAXN]; double l,r; int n; inline double cal(double mid){ double ans = 0,tmp; for(int i = 1;i <= n; ++i){ tmp = ((x[i] - mid)*(x[i] - mid) + y[i]*y[i]); if(tmp > ans ) ans = tmp; } return ans; } inline double ternary_search(double l,double r){ //三分查找求最小值 while(l + EPS < r){ double left = (2*l + r)/3; double right = (2*r + l)/3; double tmp1 = cal(left); double tmp2 = cal(right); if(tmp1 > tmp2) l = left; else r = right; } return l; } int main() { while(scanf("%d",&n),n){ l = INF; r = -INF; for(int i = 1;i <= n; ++i){ scanf("%lf%lf",&x[i],&y[i]); if(x[i] > r) r = x[i]; if(x[i] < l) l = x[i]; } double mid = ternary_search(l,r); printf("%.9lf %.9lf/n",mid,sqrt(cal(mid))); } }

你可能感兴趣的:(search)