Description
在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间
对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10
Solution
关键在于找到AB和CD上的两个点E和F,使得A-E-F-D这条路所用时间最短
观察一下可以发现当E固定时F在CD上滑动是一个凹函数,当F固定时E同理,那么三分套三分即可
Code
#include <stdio.h>
#include <string.h>
#include <math.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const double eps=0.00001;
struct pos {
double x,y;
void read() {
scanf("%lf%lf",&x,&y);
}
} A,B,C,D;
double P,Q,R;
double get_dis(pos a,pos b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double check(pos lim) {
pos l=C,r=D;
while (get_dis(l,r)>eps) {
double wx=(r.x-l.x)/3.0;
double wy=(r.y-l.y)/3.0;
pos midl=(pos) {l.x+wx,l.y+wy};
pos midr=(pos) {r.x-wx,r.y-wy};
double retl=get_dis(A,lim)/P+get_dis(lim,midl)/R+get_dis(midl,D)/Q;
double retr=get_dis(A,lim)/P+get_dis(lim,midr)/R+get_dis(midr,D)/Q;
if (retl>=retr) l=midl;
else r=midr;
}
return get_dis(A,lim)/P+get_dis(lim,l)/R+get_dis(l,D)/Q;
}
int main(void) {
A.read(); B.read();
C.read(); D.read();
scanf("%lf%lf%lf",&P,&Q,&R);
pos l=A,r=B;
while (get_dis(l,r)>eps) {
double wx=(r.x-l.x)/3.0;
double wy=(r.y-l.y)/3.0;
pos midl=(pos) {l.x+wx,l.y+wy};
pos midr=(pos) {r.x-wx,r.y-wy};
double retl=check(midl);
double retr=check(midr);
if (retl>=retr) l=midl;
else r=midr;
}
printf("%.2lf\n", check(l));
return 0;
}