1. 程式人生 > >【HIHOCODER 1142】 三分·三分求極值

【HIHOCODER 1142】 三分·三分求極值

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】 三分·三分求極值