您的位置:首页 > 其它

【bzoj1857】[Scoi2010]传送带 三分套三分

2017-10-31 14:48 519 查看
题目描述

在一个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

题解

三分套三分

显然路线是A->AB段上的某个点M->CD段上的某个点N->D。

容易发现,如果固定了点M,那么时间与N的位置的关系是一个单峰函数。并且在N为最优解的情况下,时间与M的位置的关系也是一个单峰函数。

于是三分套三分即可。三分M的位置,然后求最优解的过程中三分N的位置即可。

时间复杂度$O(cnt^2)$

#include <cmath>
#include <cstdio>
struct data
{
double x , y;
data() {}
data(double a , double b) {x = a , y = b;}
data operator+(data a) {return data(x + a.x , y + a.y);}
data operator*(int a) {return data(x * a , y * a);}
data operator/(int a) {return data(x / a , y / a);}
}A , B , C , D;
double P , Q , R;
inline double dis(data a , data b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double solve(data M)
{
data l = C , r = D , mid1 , mid2;
int cnt = 50;
while(cnt -- )
{
mid1 = (l * 2 + r) / 3 , mid2 = (l + r * 2) / 3;
if(dis(M , mid1) / R + dis(mid1 , D) / Q < dis(M , mid2) / R + dis(mid2 , D) / Q) r = mid2;
else l = mid1;
}
return dis(A , M) / P + dis(M , l) / R + dis(l , D) / Q;
}
int main()
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf" , &A.x , &A.y , &B.x , &B.y , &C.x , &C.y , &D.x , &D.y , &P , &Q , &R);
data l = A , r = B , mid1 , mid2;
int cnt = 50;
while(cnt -- )
{
mid1 = (l * 2 + r) / 3 , mid2 = (l + r * 2) / 3;
if(solve(mid1) < solve(mid2)) r = mid2;
else l = mid1;
}
printf("%.2lf\n" , solve(l));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: