今天刷了一道hihoCoder上的一道题,用三分法求极值问题,感觉挺有意思,不多说题目如下:
提示:三分法
第1行:5个整数a,b,c,x,y。前三个数构成抛物线的参数,后两个数x,y表示P点坐标。-200≤a,b,c,x,y≤200
第1行:1个实数d,保留3位小数(四舍五入)
2 8 2 -2 6样例输出
2.437
#include
#include
using namespace std;
const double EPSINON = 0.000001;
int a,b,c,x,y;
double Distance(double tempx)
{
return sqrt(pow(tempx-x, 2) + pow(a*tempx*tempx+b*tempx+c-y, 2));
}
double Calculate(double left, double right, double dist_left, double dist_right)
{
double temp = (right-left)/3.0; //把区间等分为三块
double temp_left = left+temp;
double temp_right = right-temp;
double ldist = Distance(temp_left);
double rdist = Distance(temp_right);
if(fabs(left-right) < EPSINON ){ //终止条件
return (dist_left+dist_right)/2;
}
else{
if(ldist < rdist){ //左区间的距离小的话,就在左边找
return Calculate(left, temp_right, dist_left, rdist);
}
else if(ldist > rdist){ //右区间的距离小的话,就在右边找
return Calculate(temp_left, right, ldist, dist_right);
}
else{ //左右相等,则在中间找
return Calculate(temp_left, temp_right, ldist, rdist);
}
}
}
int main()
{
cin>>a>>b>>c>>x>>y;
double result = 0;
double mid;
double width = 500.0;
mid = static_cast(-b)/(2*a);
if(x > mid){
result = Calculate(mid,mid+width, Distance(mid), Distance(mid+width));
}
else if(x < mid){
result = Calculate(mid-width, mid, Distance(mid-width), Distance(mid));
}
else{ //当点在对称轴上时,取点到抛物线顶点的距离和根据算法算出来的距离的最小值
result = min(Distance(x), Calculate(mid, mid+width, Distance(mid), Distance(mid+width)));
}
printf("%.3lf", result);
system("pause");
return 0;
}
非递归方法:
#include