【题目链接】click here~~
【题目大意】求x轴上一点到各点的最大值中的最小值 点到线段距离
【解题思路】三分查找
三分查找初学可以参考这篇博客分析:三分查找,写的很详细了,其实跟类似于二分查找,理解了如何构造,代码不难实现
方法1:
#include <bits/stdc++.h>
using namespace std;
const double eps=1e-7;
const double inf=0x3f3f3f3f;
const int N=55000;
int n;
struct point
{
double x,y;
}mapp[N];
double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double getmax(double x) //最长边,最长时间
{
double maxx=eps;
point q={x,0};
for(int i=0;i<n;i++)
{
double p=dis(q,mapp[i]);
maxx=max(maxx,p);
}
return maxx;
}
int main()
{
//freopen("1.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
double pleft=N,pright=-N;
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&mapp[i].x,&mapp[i].y);
pleft=min(pleft,mapp[i].x); //左边界
pright=max(pright,mapp[i].x);//右边界
}
while((pright-pleft)>eps)
{
double mid=(pright-pleft)/3;
double l,r;
l=pleft+mid,r=pleft+2*mid;
if(getmax(l)>=getmax(r)) pleft=l;
else pright=r;
}
printf("%.9f %.9f\n",pleft,getmax(pleft));
}
return 0;
}方法2:
#include <bits/stdc++.h>
using namespace std;
const int N=55000;
const double eps=1e-7;
int n,m;
struct point{
double x,y;
}mapp[N];
double disget(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double getmax(double x){//求最大边,最长时间
point q={x,0};
double maxx=eps;
for(int i=0;i<n;i++){
double p=disget(q,mapp[i]);
maxx=max(maxx,p);
}
return maxx;
}
double solve(){//赋初值时,最好直接赋数字!
double pleft=-200000,pright=200000;
double mid,midd,mid_area,midd_area ;
while(pright-pleft>eps){
mid=(pleft+pright)/2.0 ;
midd=(mid+pright)/2.0 ;
mid_area=getmax(mid) ;
midd_area=getmax(midd) ;
if(mid_area<=midd_area) pright=midd ;
else pleft=mid ;
}
return midd ;
}
int main()
{
while(scanf("%d",&n)!=EOF){
if(n==0) break;
for(int i=0;i<n;i++){
scanf("%lf%lf",&mapp[i].x,&mapp[i].y);
}
double res=solve();
printf("%.9f %.9f\n",res,getmax(res));
}
return 0;
}
BNU 4260 Trick or Treat && ZOJ 3386 (三分查找)
原文:http://blog.csdn.net/u013050857/article/details/45340393