[SCOI2010]傳送帶 三分法
阿新 • • 發佈:2018-12-21
[SCOI2010]傳送帶
三分法模板。
關於為什麼可以三分,我選擇感性理解,有人證明了,總之我是懶得證了。
假設路徑是\(A \to E \to F \to D\),\(E\)和\(F\)分別是從\(AB\)到平面上的拐角和從平面上到\(CD\)上的拐角。首先三分\(E\)的位置,在此基礎上三分\(F\)的位置就可以了。
#include<cstdio> #include<cmath> #define I inline #define D double using namespace std; const D eps=1e-6; struct N{D x,y;}a,b,c,d; D P,Q,R; I D pwr(D x){return x*x;} I D dst(N a,N b){return sqrt(pwr(a.x-b.x)+pwr(a.y-b.y));} D dac0(N f){ N l=c,r=d,p,q; D u,v,o,e; while(dst(l,r)>eps) u=(r.x-l.x)/3,v=(r.y-l.y)/3,p=(N){l.x+u,l.y+v},q=(N){r.x-u,r.y-v},o=dst(f,p)/R+dst(p,d)/Q,e=dst(f,q)/R+dst(q,d)/Q,e-o>eps?r=q:l=p; return dst(f,l)/R+dst(l,d)/Q; } D dac(){ N l=a,r=b,p,q; D u,v,o,e; while(dst(l,r)>eps) u=(r.x-l.x)/3,v=(r.y-l.y)/3,p=(N){l.x+u,l.y+v},q=(N){r.x-u,r.y-v},o=dst(a,p)/P+dac0(p),e=dst(a,q)/P+dac0(q),e-o>eps?r=q:l=p; return dac0(l)+dst(a,l)/P; } int main(){ scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y,&P,&Q,&R); printf("%.2lf",dac()); return 0; }