原题链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3400
题目大意:
AB间速度为P,CD间速度为Q,其余为R;
求A到D所需最短时间。
思路:
在AB间找到一点x,cd间找到一点y,使得A-x-y-D所需时间最短。
过程(个人理解):
用三分法在AB间找到一个x点,然后三分CD,找到对应x点的最优y,使得该x对应的x-y-D所需时间最短。
因为AB也在三分,所以会不断刷新x的值,使x趋向于最优。
最终找到最优A-x-y-D。
代码如下:
#include<iostream>
#include<cmath>
#include<utility>
using namespace std;
pair<double, double>a, b, c, d;
double P, Q, R;
double dis(pair<double, double>x, pair<double, double>y)//两点间距离
{
return sqrt((x.first - y.first)*(x.first - y.first) + (x.second - y.second)*(x.second - y.second));
}
double MINCD(pair<double, double>x)//CD间三分,x为AB上的x
{
double time1=0, time2=0;
pair<double, double>midleft, midright;
pair<double, double>left = c;
pair<double, double>right = d;
do{
midleft.first = (left.first * 2 + right.first) / 3.0;
midleft.second = (left.second * 2 + right.second) / 3.0;
midright.first = (left.first + right.first * 2) / 3.0;
midright.second = (left.second + right.second * 2) / 3.0;
time1 = dis(d, midleft) / Q + dis(x, midleft) / R;
time2 = dis(d, midright) / Q + dis(x, midright) / R;
if (time1 > time2)
left = midleft;
else right = midright;
} while (abs(time1 - time2) > 0.000001);
return time1;
}
double MINAB()//AB间三分
{
double time1=0, time2=0;
pair<double, double>midleft, midright;
pair<double, double>left = a;
pair<double, double>right = b;
do{
midleft.first = (left.first * 2 + right.first) / 3;
midleft.second = (left.second * 2 + right.second) / 3;
midright.first = (left.first + right.first * 2) / 3;
midright.second = (left.second + right.second * 2) / 3;
time1 = dis(a, midleft) / P + MINCD(midleft);
time2 = dis(a, midright) / P + MINCD(midright);
if (time1 > time2)
left = midleft;
else right = midright;
} while (abs(time1 - time2) > 0.000001);
return time1;
}
int main()
{
int T;
cin >> T;
while (T--)
{
//scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", &a.first, &a.second, &b.first, &b.second, &c.first, &c.second, &d.first, &d.second, &P, &Q, &R);
cin >> a.first >> a.second >> b.first >> b.second;
cin >> c.first >> c.second >> d.first >> d.second;
cin >> P >> Q >> R;
printf("%.2lf\n", MINAB());
}
return 0;
}