Description
在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间
Input
输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy
第三行是3个整数,分别是P,Q,R
Output
输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留到小数点后2位
Sample Input
0 0 0 100
100 0 100 100
2 2 1
Sample Output
136.60
HINT
对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000 1<=P,Q,R<=10
题解
对于一条线段,设他的开始点为A,结束点为B
设枚举了一个点u,暂时不看另外一条线段,直接设他到D点
那么通过点u到达D的时间其实就是线段Au和线段uD,分别除速度
然后意会一下,在u逐渐远离A的过程中,Au会增大而uD会减小,除以速度后其实是一个二次函数,那么这是有顶点的嘛,所以我们三分
那另一条线段怎么处理呢?也是一样啊,对于我们第一条线段三分出来的答案,我们第二条线段三分最优点与之配对。所以就是三分套三分啦
代码可读性 应该还是有的
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-4;
double ans=0.0,p,q,R;
double ax,ay,bx,by,cx,cy,dx,dy;
double K[2],B[2];
void gt(double x1,double y1,double x2,double y2,int op)
{
K[op]=(y1-y2)/(x1-x2);
B[op]=y1-K[op]*x1;
}
double sqr(double u){return u*u;}
double dis(double x1,double y1,double x2,double y2){return sqrt(sqr(x1-x2)+sqr(y1-y2));}
double fd(double x1,double y1,double U)
{
double V=K[1]*U+B[1];
return dis(ax,ay,x1,y1)/p+dis(x1,y1,U,V)/R+dis(U,V,dx,dy)/q;
}
double fda(double x1,double y1,double V)
{
double U=cx;
return dis(ax,ay,x1,y1)/p+dis(x1,y1,U,V)/R+dis(U,V,dx,dy)/q;
}
double fdsum(double u)
{
double v=K[0]*u+B[0];
double ll=min(cx,dx),rr=max(cx,dx);
if(cx!=dx)
{
while(ll+eps<=rr)
{
double midx=(ll+rr)/2;
double mmidx=(midx+rr)/2;
if(fd(u,v,midx)<fd(u,v,mmidx))rr=mmidx;
else ll=midx;
}
return fd(u,v,ll);
}
else
{
ll=min(cy,dy),rr=max(cy,dy);
while(ll+eps<=rr)
{
double midx=(ll+rr)/2;
double mmidx=(midx+rr)/2;
if(fda(u,v,midx)<fda(u,v,mmidx))rr=mmidx;
else ll=midx;
}
return fda(u,v,ll);
}
}
double check(double v)
{
double u=ax;
double ll=min(cx,dx),rr=max(cx,dx);
if(cx!=dx)
{
while(ll+eps<=rr)
{
double midx=(ll+rr)/2;
double mmidx=(midx+rr)/2;
if(fd(u,v,midx)<fd(u,v,mmidx))rr=mmidx;
else ll=midx;
}
return fd(u,v,ll);
}
else
{
ll=min(cy,dy),rr=max(cy,dy);
while(ll+eps<=rr)
{
double midx=(ll+rr)/2;
double mmidx=(midx+rr)/2;
if(fda(u,v,midx)<fda(u,v,mmidx))rr=mmidx;
else ll=midx;
}
return fda(u,v,ll);
}
}
int main()
{
scanf("%lf%lf%lf%lf",&ax,&ay,&bx,&by);
if(ax!=bx)gt(ax,ay,bx,by,0);
scanf("%lf%lf%lf%lf",&cx,&cy,&dx,&dy);
if(cx!=dx)gt(cx,cy,dx,dy,1);
scanf("%lf%lf%lf",&p,&q,&R);
if(ax==bx)
{
double l=min(ay,by),r=max(ay,by);
while(l+eps<=r)
{
double mid=(l+r)/2;
double mmid=(mid+r)/2;
if(check(mid)<check(mmid))r=mmid;
else l=mid;
}
printf("%.2lf\n",check(l));
}
else
{
double l=min(ax,bx),r=max(ax,bx);
while(l+eps<=r)
{
double mid=(l+r)/2;
double mmid=(mid+r)/2;
if(fdsum(mid)<fdsum(mmid))r=mmid;
else l=mid;
}
printf("%.2lf\n",fdsum(l));
}
return 0;
}