您的位置:首页 > 其它

HDU 3400 Line belt

2016-07-25 16:22 344 查看
题目:

Description

In a two-dimensional plane there are two line belts, there are two segments AB and CD, lxhgww's speed on AB is P and on CD is Q, he can move with the speed R on other area on the plane.

How long must he take to travel from A to D?

Input

The first line is the case number T.

For each case, there are three lines.

The first line, four integers, the coordinates of A and B: Ax Ay Bx By.

The second line , four integers, the coordinates of C and D:Cx Cy Dx Dy.

The third line, three integers, P Q R.

0<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000

1<=P,Q,R<=10

Output

The minimum time to travel from A to D, round to two decimals.

Sample Input

1
0 0 0 100
100 0 100 100
2 2 1


Sample Output

136.60




就是求从A到E到F到D的最短时间。

这个题目,就是所谓的三分套三分。

假设AE/AB=mid,DF/CD=t

对每个点E,可以求出E到F到D的最短时间,这个我用函数f 实现了。

因为E到D的时间 f(t) 是凹函数,所以很容易用三分求出来。

但是总时间是不是关于mid即E点的位置是单峰函数,这个还有待考虑。

感觉应该是的,不过又证明不了。

有一个定理倒是和这个类似,n个上凸函数的和一定是上凸函数。

代码:

#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;

double time(double x, double y, int cx, int cy, int dx, int dy, double t,int r,int q)
{
double l = sqrt((dx - cx)*(dx - cx) + (dy - cy)*(dy - cy));
double x2 = t*cx + (1 - t)*dx;
double y2 = t*cy + (1 - t)*dy;
return sqrt((x - x2)*(x - x2) + (y - y2)*(y - y2))/r+l*t/q;
}

double f(double x, double y, int cx, int cy, int dx, int dy,int r,int q)
{
double low = 0, high = 1;
double mid, mm;
while (low + 0.0000001 < high)
{
mid = (low + high) / 2;
mm = (mid + high) / 2;
if (time(x,y,cx,cy,dx,dy,mid,r,q)<time(x,y,cx,cy,dx,dy,mm,r,q))high = mm;
else low = mid;
}
return time(x, y, cx, cy, dx, dy, mid, r, q);
}

int main()
{
int t;
int ax, ay, bx, by, cx, cy, dx, dy;
int p, q, r;
cin >> t;
while (t--)
{
cin >> ax >> ay >> bx >> by >> cx >> cy >> dx >> dy;
cin >> p >> q >> r;
double low = 0, high = 1;
double mid, mm;
double l = sqrt((ax - bx)*(ax - bx) + (ay - by)*(ay - by));
while (low + 0.00000001 < high)
{
mid = (low + high) / 2;
mm = (mid + high) / 2;
if (f(mid*bx + (1 - mid)*ax, mid*by + (1 - mid)*ay, cx, cy, dx, dy, r, q) + l*mid / p <

f(mm*bx + (1 - mm)*ax, mm*by + (1 - mm)*ay, cx, cy, dx, dy, r, q) + l*mm / p)high = mm;
else low = mid;
}
cout <<fixed<<setprecision(2)<<

f(mid*bx + (1 - mid)*ax, mid*by + (1 - mid)*ay, cx, cy, dx, dy, r, q) + l*mid / p << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: