bzoj1857 SCOI2010传送带

    xiaoxiao2025-04-01  13

    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先进行三分,为什么不是二分?因为我们发现没有让我们二分的判断条件,而在三分的时候,你只要手玩半个小时就会发现规律: 我们设每次三分出的两个点为ij。 如果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.

    这可以算是三分套三分的模板吧。

    转载请注明原文地址: https://ju.6miu.com/read-1297617.html
    最新回复(0)