思路:要求最短时间从A到D,则走的路线一定是AB上的一段,CD上的一段,AB与CD之间的一段。
那么可以先三分得到AB上的一个点,在由这个点三分CD!!
代码如下:
#include<iostream> #include<stdio.h> #include<algorithm> #include<iomanip> #include<cmath> #include<cstring> #include<vector> #define ll __int64 #define pi acos(-1.0) using namespace std; double P,Q,R,ab,cd; struct point { double x,y; }an[4],pp,qq; int n; double dis(point &a,point &b) { return sqrt(1e-5+(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));//注意这里要加上1e-5 } double cal2(double t) { qq.x=an[3].x+(an[2].x-an[3].x)/cd*t*Q; qq.y=an[3].y+(an[2].y-an[3].y)/cd*t*Q; return dis(pp,qq)/R+t; } double cal(double t) { double l,r,mid,mmid,ans; pp.x=an[0].x+(an[1].x-an[0].x)/ab*t*P; pp.y=an[0].y+(an[1].y-an[0].y)/ab*t*P; l=0.0;r=cd/Q; while((1e-5+l)<r){ mid=(r+l)/2; mmid=(mid+r)/2; ans=cal2(mid); if((ans+1e-5)<cal2(mmid)) r=mmid; else l=mid; } return ans+t; } int main(){ int t,i; double l,r,mid,mmid,ans; cin>>t; while(t--){ for(i=0;i<4;i++) cin>>an[i].x>>an[i].y; cin>>P>>Q>>R; ab=dis(an[0],an[1]); cd=dis(an[2],an[3]); l=0.0;r=ab/P; while((1e-5+l)<r){ mid=(r+l)/2; mmid=(mid+r)/2; ans=cal(mid); if((ans+1e-5)<cal(mmid)) r=mmid; else l=mid; } printf("%.2lf ",ans); } return 0; }