【HIHOCODER 1142】 三分·三分求極值
阿新 • • 發佈:2017-11-28
int code mar 描述 while 不知道 == class mat
這個點將這個拋物線分成兩個單調曲線,這兩個曲線與某個固定點的距離函數是凸函數。
即用三分解決
描述
這一次我們就簡單一點了,題目在此:
在直角坐標系中有一條拋物線y=ax^2+bx+c和一個點P(x,y),求點P到拋物線的最短距離d。
輸入
第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
題解
拋物線和點之間的距離可以簡單的用直線公式計算:
\(d = min{sqrt((X - x)^2+(aX^2+bX+c-y)^2)}\)
直接看這個公式,完全不知道它是否為凸函數。
可以考慮選擇拋物線極值點\((-\frac{b}{2a},\frac{4ac-b^2}{4a})\)
這個點將這個拋物線分成兩個單調曲線,這兩個曲線與某個固定點的距離函數是凸函數。
即用三分解決
#include <bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define PI acos(-1)
#define bug puts("here")
#define REP(i,x,n) for(int i=x;i<=n;i++)
#define DEP(i,n,x) for(int i=n;i>=x;i--)
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const double eps=1e-6;
int a,b,c,x,y;
double check(double tx){
double ty=a*tx*tx+b*tx+c;
double t=(tx-x)*(tx-x)+(ty-y)*(ty-y);
return sqrt(t);
}
int main(){
// while(1)
{
a=read(),b=read(),c=read(),x=read(),y=read();
double l=-200,r=-b/(2*a),ans;
while(fabs(l-r)>eps){
double h=(r-l)/3;
if(check(l+h)<check(l+2*h)) r=l+2*h;
else l=l+h;
}
ans=check(l);
l=-b/(2*a),r=200;
while(fabs(l-r)>eps){
double h=(r-l)/3;
if(check(l+h)<check(l+2*h)) r=l+2*h;
else l=l+h;
}
ans=min(ans,check(l));
printf("%.3f\n",ans);
}
return 0;
}
【HIHOCODER 1142】 三分·三分求極值