题意:给出 两条线段 AB CD 算出 A到D的最短时间
思路: 一步一步来 ,先利用三分 确定AB中的点,然后在三分CD中的点 最后求出最短时间
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
struct point{
double x,y;
point (){}
point (double x,double y):x(x),y(y) {}
point operator * (int a){
return point (x*a,y*a);
}
point operator / (int a){
return point(x/a,y/a);
}
point operator + (point a){
return point (x+a.x,y+a.y);
}
point operator - (point a){
return point (x-a.x,y-a.y);
}
};
point a,b,c,d;int p,q,rrr;
const double EPS=1e-9;
double dis(point e,point f){
return sqrt((e.x-f.x)*(e.x-f.x)+(e.y-f.y)*(e.y-f.y));
}
double solve(point l,point r){
return dis(l,a)/p+dis(l,r)/rrr+dis(r,d)/q;
}
double ternarySearch1(point l,point r,point k)
{
double ans=1e8;
do
{
point ll=((l*2)+r)/3;
point rr=(l+(r*2))/3;
double ans1=solve(k,ll);
double ans2=solve(k,rr);
ans=min(ans1,ans2);
if(ans1>ans2)
l=ll;
else
r=rr;
}while(dis(r,l)>EPS);
return ans;
}
double ternarySearch(point l,point r)
{
double ans=1e8;
do
{
point ll=((l*2)+r)/3;
point rr=(l+(r*2))/3;
double ans1=ternarySearch1(c,d,ll);
double ans2=ternarySearch1(c,d,rr);
ans=min(ans1,ans2);
if(ans1>ans2)
l=ll;
else
r=rr;
// cout<<ans<<endl;
}while(dis(r,l)>EPS);
return ans;
}
int main(int argc, const char * argv[]) {
int t;
cin>>t;
while (t--) {
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
scanf("%d%d%d",&p,&q,&rrr);
printf("%.2lf\n",ternarySearch(a,b));
}
return 0;
}