HDU 3400 Line belt【三分套三分】
从A出发到D,必定有从AB某个点E出发,从某个点F进入CD
故有E,F两个不确定的值。
在AB上行走的时间 f = AE / p
在其他区域行走的时间 g = EF / r
在CD上行走的时间 h = FD / q
总时间 T = f + g + h
当E确定时,T1 = g + h + C 此时g时一个先减后增的凹函数,h是一个单调递减的凹函数,根据凹函数的性质,故T1是一个凹函数
反之亦然,故需要三分确定其中一个点的位置,再三分另一个点的位置。
#include<stdio.h> #include<string.h> #include<math.h> const double eps=1e-8; struct node{ double x,y; }a,b,c,d,e,f; double p,q,r; double dis(node A,node B){ double x=A.x-B.x; double y=A.y-B.y; return sqrt(x*x+y*y); } double cal(double bi){ f.x=c.x+(d.x-c.x)*bi; f.y=c.y+(d.y-c.y)*bi; return dis(e,f)/r+dis(f,d)/q; } double find2(double bi){ e.x=a.x+(b.x-a.x)*bi; e.y=a.y+(b.y-a.y)*bi; double l=0,r=1,mid,mmid; while(r-l>eps){ mid=(l+r)/2; mmid=(mid+r)/2; if(cal(mid)<cal(mmid)) r=mmid; else l=mid; } return cal(l)+dis(a,e)/p; } double find1(){ double l=0,r=1,mid,mmid; while(r-l>eps){ mid=(l+r)/2; mmid=(mid+r)/2; if(find2(mid)<find2(mmid)) r=mmid; else l=mid; } return find2(l); } int main(){ int t; scanf("%d",&t); while(t--){ 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",&p,&q,&r); printf("%.2f\n",find1()); } return 0; }