【SCOI2010】【傳送帶】【三分答案】
阿新 • • 發佈:2019-02-02
題目大意
平面上有兩條傳送帶,在上面行走有一定的速度,在平面其他地方行走有一定速度,求從一條傳送帶一端走到另一條一端的時間。
解題思路
顯然在兩條傳送帶都走一段後走平面,當一個轉折點確定後,距離就是一個單峰函式,可以用三分解決,總的就是三分套三分。由於資料較小精度要求較小,可以暴力一個轉折點再三分。
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;
}