1439:【SCOI2010】傳送帶
時間限制: 2000 ms 內存限制: 65536 KB
提交數: 372 通過數: 212
【題目描述】
在一個2維平面上有兩條傳送帶,每一條傳送帶可以看成是一條線段。兩條傳送帶分別爲線段AB和線段CD。lxhgww在AB上的移動速度爲P,在CD上的移動速度爲Q,在平面上的移動速度R。現在lxhgww想從A點走到D點,他想知道最少需要走多長時間。
【輸入】
輸入數據第一行是4個整數,表示A和B的座標,分別爲Ax,Ay,Bx,By
第二行是4個整數,表示C和D的座標,分別爲Cx,Cy,Dx,Dy
第三行是3個整數,分別是P,Q,R
【輸出】
輸出數據爲一行,表示lxhgww從A點走到D點的最短時間,保留到小數點後2位
【輸入樣例】
0 0 0 100
100 0 100 100
2 2 1
【輸出樣例】
136.60
【提示】
【數據範圍】
對於100%的數據,1≤ Ax,Ay,Bx,By,Cx,Cy,Dx,Dy≤1000
1≤P,Q,R≤10
思路:有兩條線段AB,CD,在AB上行走的速度爲p,CD上行走的速度爲q,平面裏行走的速度爲r(r>p,q)。求從A走到D的最短距離。
路線都是AE—EF—FD,不妨先把E點定下來,現在要求EF/r+FD/q的最小值,用勾股定理的表示出來發現它是一個單峯函數,是可以用三分法求出來的。
————————————————
#include<bits/stdc++.h>
#define eps 1e-8
using namespace std;
struct Point{
double x,y;
Point(){};
Point(double xx,double yy):x(xx),y(yy){};
Point operator / (double a){return Point(x/a, y/a);}
Point operator - (const Point &a){return Point(x-a.x, y-a.y);}
Point operator + (const Point &a){return Point(x+a.x, y+a.y);}
}A,B,C,D;
double P,Q,R;
double dis(Point a,Point b){
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
double calc(Point X){
Point l = C, r = D;
while(dis(l,r) > eps){
Point x = (r - l) / 3;
Point lmid = l + x, rmid = r - x;
double ans1 = dis(lmid,D)/Q + dis(X,lmid)/R;
double ans2 = dis(rmid,D)/Q + dis(X,rmid)/R;
if(ans2 - ans1 > eps) r = rmid;
else l = lmid;
} return dis(l,D)/Q + dis(X,l)/R;
}
double Solve(){
Point l = A, r = B;
while(dis(l,r) > eps){
Point x = (r - l) / 3;
Point lmid = l + x, rmid = r - x;
double ans1 = calc(lmid) + dis(lmid, A)/P;
double ans2 = calc(rmid) + dis(rmid, A)/P;
if(ans2 - ans1 > eps) r = rmid;
else l = lmid;
} return calc(l) + dis(l,A)/P;
}
int main(){
scanf("%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y);
scanf("%lf%lf%lf%lf",&C.x,&C.y,&D.x,&D.y);
scanf("%lf%lf%lf",&P,&Q,&R);
printf("%0.2lf", Solve()); return 0;
}