做题感悟:刚开始研究三分就碰上这一题,想了老半天必须确定两个点才能算出总时间,但是没想出来怎么做。
解题思路:设:两条线段分别为 AB和CD,AB线段上的速度为V1,CD线段上的速度为V2,别的地方为V3,如果想从A点到D点,必须在AB上确定一个点X,在CD上确定一点Y,然后路程就是A->X->Y->D ,这样先三分线段AB,在三分AB的同时,每找到 X 都同时三分CD,在CD上找到一个最优的Y,然后取逼近最短时间。
代码:
#include<stdio.h> #include<iostream> #include<map> #include<string> #include<string.h> #include<stdlib.h> #include<math.h> #include<queue> #include<algorithm> using namespace std ; const double eps = 0.00001 ; double A,B,C ; struct node { double x,y ; } ; double dis(node a,node b) // 求两点距离 { return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0)) ; } node mx(node a,node b) // 求两点中点 { node c ; c.x=(a.x+b.x)/2.0 ; c.y=(a.y+b.y)/2.0 ; return c ; } double time(node c,node d,node e) // 对线段cd 进行三分 { double t1,t2 ; node mid,midd ; node le=c,rt=d ; do{ mid=mx(le,rt) ; midd=mx(mid,rt) ; t1=dis(e,mid)/C+dis(mid,d)/B ; t2=dis(e,midd)/C+dis(midd,d)/B ; if(t1<t2) rt=midd ; else le=mid ; }while(dis(le,rt)>=eps) ; return (t1+t2)/2.0 ; } void print(node a,node b,node c,node d)// 对线段ab进行三分 { double T1,T2 ; node mid,midd ; node le=a,rt=b ; do{ // 用do……while()结构是因为如果第一次就不执行 mid=mx(le,rt) ; // 那 T1 ,T2就没有值,输出就错了。。 midd=mx(mid,rt) ; T1=dis(a,mid)/A+time(c,d,mid) ; T2=dis(a,midd)/A+time(c,d,midd) ; if(T1<T2) rt=midd ; else le=mid ; }while(dis(le,rt)>=eps) ; printf("%.2lf\n",(T1+T2)/2.0) ; } int main() { int T ; scanf("%d",&T) ; while(T--) { node a,b,c,d ; scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y) ; scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y) ; scanf("%lf%lf%lf",&A,&B,&C) ; print(a,b,c,d) ; } return 0 ; }