1. 程式人生 > >【SCOI2010】【傳送帶】【三分答案】

【SCOI2010】【傳送帶】【三分答案】

題目大意

平面上有兩條傳送帶,在上面行走有一定的速度,在平面其他地方行走有一定速度,求從一條傳送帶一端走到另一條一端的時間。

解題思路

顯然在兩條傳送帶都走一段後走平面,當一個轉折點確定後,距離就是一個單峰函式,可以用三分解決,總的就是三分套三分。由於資料較小精度要求較小,可以暴力一個轉折點再三分。

code

//#include<set>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LF double
#define
LL long long #define fo(i,j,k) for(int i=j;i<=k;i++) #define fd(i,j,k) for(int i=j;i>=k;i--) using namespace std; int const inf=2147483647; int ax,ay,bx,by,cx,cy,dx,dy,p,q,r; LF coun(LF x,LF y,LF xx){ LF yy=cy+((dx-cx)?(xx-cx)*(dy-cy)/(dx-cx):0); return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy))/r+
sqrt((dx-xx)*(dx-xx)+(dy-yy)*(dy-yy))/q; } LF coun2(LF x,LF y,LF yy){ LF xx=cx; return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy))/r+sqrt((dx-xx)*(dx-xx)+(dy-yy)*(dy-yy))/q; } int main(){ freopen("d.in","r",stdin); freopen("d.out","w",stdout); scanf("%d%d%d%d",&ax,&ay,&bx,&by); scanf("%d%d%d%d"
,&cx,&cy,&dx,&dy); scanf("%d%d%d",&p,&q,&r); if(ax==bx){ swap(ax,ay); swap(bx,by); swap(cx,cy); swap(dx,dy); } LF lx=min(ax,bx),rx=max(ax,bx),bi=0.01,anss=inf; LF ansx=lx,ans=inf; for(LF x=lx;x<=rx;x+=bi){ LF y=ay+((bx-ax)?(x-ax)*(by-ay)/(bx-ax):0); if(cx!=dx){ LF ll=min(cx,dx),rr=max(cx,dx); for(;ll+1e-10<rr;){ LF m1=ll+(rr-ll)/3,m2=rr-(rr-ll)/3; if(coun(x,y,m1)+1e-10<coun(x,y,m2))rr=m2; else ll=m1; } if(sqrt((x-ax)*(x-ax)+(y-ay)*(y-ay))/p+coun(x,y,ll)<ans){ ans=sqrt((x-ax)*(x-ax)+(y-ay)*(y-ay))/p+coun(x,y,ll); ansx=x; } }else{ LF ll=min(cy,dy),rr=max(cy,dy); for(;ll+1e-10<rr;){ LF m1=ll+(rr-ll)/3,m2=rr-(rr-ll)/3; if(coun2(x,y,m1)+1e-10<coun2(x,y,m2))rr=m2; else ll=m1; } if(sqrt((x-ax)*(x-ax)+(y-ay)*(y-ay))/p+coun2(x,y,ll)<ans){ ans=sqrt((x-ax)*(x-ax)+(y-ay)*(y-ay))/p+coun2(x,y,ll); ansx=x; } } } anss=min(anss,ans); lx=max(ax*1.0,ansx-bi*30);rx=min(bx*1.0,ansx+bi*30);bi/=10; printf("%.2lf",anss); return 0; }