1682: 三分求极值
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 91 Solved: 35
[ Submit][ Status][ Web Board]
Description
在直角坐标系中有一条抛物线y=ax^2+bx+c和一个点P(x,y),求点P到抛物线的最短距离d。
Input
第1行:5个整数a,b,c,x,y。前三个数构成抛物线的参数,后两个数x,y表示P点坐标。-200≤a,b,c,x,y≤200
Output
第1行:1个实数d,保留3位小数(四舍五入)
Sample Input
2 8 2 -2 6
Sample Output
2.437
【解析】
这道题已经说了三分求极值,由于抛物线是凸型函数所以我们二分法肯定是不行了,我们这个时候要用到三分法。
首先我们要求出mid=left+right,还有就是mid1我们需要知道等于(mid+right)/2。图画的有点丑..不过大概就是
这
个思想了。然后我们通过比较要让left和right的值相差最小,这样我们就能求得较为精确的解了,还有就是我们这
里计算距离是计算点与点之间的距离。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
double a,b,c,x,y;
double jisuan(double x1)
{
return sqrt((x1-x)*(x1-x)+(a*x1*x1+b*x1+c-y)*(a*x1*x1+b*x1+c-y));//计算两点间的距离
}
int main()
{
double left,right,mid,mid1;
double value,value1;
while(~scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&x,&y))
{
left=-1000;
right=1000;
while(left+1e-6<right)//两者相差1e-6左右就已经很精确了
{
mid=(left+right)/2;//先分为中间
mid1=(mid+right)/2;//再把中间和右边分一下
value=jisuan(mid);
value1=jisuan(mid1);
if(value<=value1)//比较那个比较小
right=mid1;//mid位置比较小,所以我们就把mid1给right
else
left=mid;//mid1位置比较小,所以我们就把mid给left
}
printf("%.3f\n",jisuan(left));
}
return 0;
}