三分--bzoj1857: [Scoi2010]傳送帶
阿新 • • 發佈:2018-12-12
三分套三分
證明很噁心。。大概就是確定了在ab上走多長
就可以列出一個關於在cd上走的路程關於時間的函式式,然後這個函式是單峰的
相似的,在ab上走的路程關於時間的函式也是單峰的
所以就可以三分套三分
注意:a和b,c和d可能在一個點上
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; double ax,ay,bx,by,cx,cy,dx,dy,p,q,r,ans,ab,cd; const double eps=1e-5; inline double dis(double x1,double y1,double x2,double y2){ return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } inline double calc(double x,double y){ double nx1,ny1,nx2,ny2; if(ab==0) nx1=ax,ny1=ay; else nx1=(bx-ax)*x/ab+ax,ny1=(by-ay)*x/ab+ay; if(cd==0) nx2=dx,ny2=dy; else nx2=(cx-dx)*y/cd+dx,ny2=(cy-dy)*y/cd+dy; return x/p+y/q+dis(nx1,ny1,nx2,ny2)/r; } inline double solve(double a){ double l=0,r=cd,res=0; do{ double midl=(l*2+r)/3,midr=(l+r*2)/3; if(calc(a,midl)<=calc(a,midr)) r=midr,res=midl; else l=midl,res=midr; }while(r-l>eps); return calc(a,res); } int main(){ scanf("%lf%lf%lf%lf",&ax,&ay,&bx,&by); scanf("%lf%lf%lf%lf",&cx,&cy,&dx,&dy); scanf("%lf%lf%lf",&p,&q,&r); ab=dis(ax,ay,bx,by),cd=dis(cx,cy,dx,dy); double l=0,r=ab; do{ double midl=(l*2+r)/3,midr=(l+r*2)/3; if(solve(midl)<=solve(midr)) r=midr,ans=midl; else l=midl,ans=midr; }while(r-l>eps); printf("%.2lf\n",solve(ans)); return 0; }