NOIPの模拟

    xiaoxiao2025-05-20  11

    题目

    Description

    在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。FTD在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在FTD想从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

    Data Constraint

    对于30%的数据 1<=Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=10 1<=P,Q,R<=5 对于100%的数据 1<=Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000 1<=P,Q,R<=10

    题目大意

    现在我们有一个二维的平面,有一只人想要从A点走到D点,那只人在平面上,在AB这条线段上,在CD这条线段上有三个可能不同的速度,求从A点到D点所需要最短的距离

    比赛时の想法

    在草稿纸上比划了一会儿后,发现答案的路径是在AB和CD两条路线上都选择一个点,然后路径就是:A->第一个点->第二个点->D(当然,两个点都是有可能在线段的顶点上的)于是我就开始思考怎么确定两个点的位置,这是想到了GDOI的DAY1T1感觉有点像,但是不会很会打啊/(ㄒoㄒ)/~~于是开始想其他的方法,又想到了可以先以1位精度来找到最优的两个点,再以0.001位精度再找一次(第二次查找的范围是±1)这样就可以在 10002 的时间内解决这个问题了,虽然我觉得这个方法是可行的,但是又证明不了正确性,最后错了两个小细节,只拿了一部分的分数

    正解

    三分套三分,对于一个下凹的二次函数,我们任意选择两个点,分别为 xi,xj(i<j) 在二次函数上对应的y值为 yi,yj 那么有以下三种情况: 1: yi>yj ,此时函数的峰值在 xi 2: yi<yj ,此时函数的峰值在 xj 3: yi=yj ,此时函数的峰值在 xixj 其实对于一个上凹的单峰函数也是一样的,证明的话就不做了,省得画图伤了你们的眼睛(〃>皿<)

    贴代码

    var ax,ay,bx,by,cx,cy,dx,dy,p,q,r,i,j,k,l,t1,t2,t3,t4:longint; x,y,x1,y1,k1,k2,b1,b2,ans,tot,ii,jj:extended; begin readln(ax,ay,bx,by); readln(cx,cy,dx,dy); readln(p,q,r); if ax=bx then k1:=0 else k1:=(ay-by)/(ax-bx); b1:=ay-k1*ax; if cx=dx then k2:=0 else k2:=(cy-dy)/(cx-dx); b2:=cy-k2*cx; if (k1=0) or (k2=0) then begin l:=ax; ax:=ay; ay:=l; l:=bx; bx:=by; by:=l; l:=cx; cx:=cy; cy:=l; l:=dx; dx:=dy; dy:=l; if ax=bx then k1:=0 else k1:=(ay-by)/(ax-bx); b1:=ay-k1*ax; if cx=dx then k2:=0 else k2:=(cy-dy)/(cx-dx); b2:=cy-k2*cx; end; ans:=9999999; if ax>bx then begin t1:=bx; t2:=ax; end else begin t1:=ax; t2:=bx; end; if cx>dx then begin t3:=dx; t4:=cx; end else begin t3:=cx; t4:=dx; end; for i:=t1 to t2 do begin for j:=t3 to t4 do begin x:=k1*i+b1; y:=k2*j+b2; tot:=sqrt((i-ax)*(i-ax)+(x-ay)*(x-ay))/p; tot:=tot+sqrt((j-i)*(j-i)+(y-x)*(y-x))/r; tot:=tot+sqrt((dx-j)*(dx-j)+(dy-y)*(dy-y))/q; if tot<ans then begin x1:=i; y1:=j; ans:=tot; end; end; end; ii:=x1-1; while ii<=x1+1 do begin ii:=ii+0.001; if ii<t1 then continue; if ii>t2 then break; x:=k1*ii+b1; for k:=-1000 to 1000 do begin jj:=y1+k/1000; if jj<t3 then continue; if jj>t4 then break; y:=k2*jj+b2; tot:=sqrt((ii-ax)*(ii-ax)+(x-ay)*(x-ay))/p; tot:=tot+sqrt((jj-ii)*(jj-ii)+(y-x)*(y-x))/r; tot:=tot+sqrt((dx-jj)*(dx-jj)+(dy-y)*(dy-y))/q; if tot<ans then ans:=tot; end; end; writeln(ans:0:2); end.
    转载请注明原文地址: https://ju.6miu.com/read-1299077.html
    最新回复(0)