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
题意是很好理解的,你会发现所有的路径总会经过三个速度不同的地方,也就是说AB,CD和其他地方是必定会经过的,所以我们就可以对AB先进行三分,为什么不是二分?因为我们发现没有让我们二分的判断条件,而在三分的时候,你只要手玩半个小时就会发现规律:
我们设每次三分出的两个点为i,j。
如果solve(i)<solve(j)则答案区间必定在ij之间否则l:=i;
然后同样的再对CD套一个三分就可以了。
type node=record
x,y:real;
end;
var
i,j,n:longint;
a:array[0..4]of node;
v1,v2:node;
p,q,m:real;
function dis(x1,y1,x2,y2:real):real;
begin
exit(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
end;
function get_dis(l1,l2:real):real;
var
x1,x2,y1,y2:real;
begin
x1:=A[0].x+v1.x*l1;
y1:=A[0].y+v1.y*l1;
x2:=A[3].x+v2.x*l2;
y2:=A[3].y+v2.y*l2;
//writeln(x1:0:2,' ',y1:0:2,' ',x2:0:2,' ',y2:0:2,' ',r:0:2);
exit(dis(a[0].x,a[0].y,x1,y1)/p+dis(x1,y1,x2,y2)/m+dis(x2,y2,A[3].x,A[3].y)/Q);
end;
function solve(l1:real):real;
var
l,r,mid1,mid2,k1,k2:real;
i:longint;
begin
l:=0;
r:=1;
for i:=1 to 200 do
begin
mid1:=(l+r)/2;
mid2:=(mid1+r)/2;
k1:=get_dis(l1,mid1);
k2:=get_dis(l1,mid2);
if(k1<k2)then r:=mid2 else l:=mid1;
end;
exit(get_dis(l1,l));
end;
procedure main;
var
i:longint;
l,r,mid1,mid2,k1,k2:real;
begin
for i:=0 to 3 do read(a[i].x,a[i].y);
readln(p,q,m);
v1.x:=A[1].x-A[0].x;
v1.y:=A[1].y-A[0].y;
v2.x:=A[2].x-A[3].x;
v2.y:=A[2].y-A[3].y;
l:=0;
r:=1;
for i:=1 to 200 do
begin
mid1:=(l+r)/2;
mid2:=(mid1+r)/2;
k1:=solve(mid1);
k2:=solve(mid2);
if(k1<k2)then r:=mid2 else l:=mid1;
end;
writeln(solve(l):0:2);
end;
begin
main;
end.
这可以算是三分套三分的模板吧。