HDU 3400 Line belt【三分法】

题意: 有两条线段,在其中一条线段上移动的速度为 v1,在另一条线上速度为v2, 在其他地方移动速度为 r,问从其中一条线段的一个端点移动到另一个线段

           的一个端点的最少时间。

分析: 在其中一条线段上三分离开的点,枚举之后再进行一次三分求最优解,关键在于看出函数是凸性的。

#include<stdio.h>
#include<string.h>
#include<math.h>
const double eps=1e-6;
struct node
{
    double x,y;
};
double dis(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double v1,v2,R;

double tcal(node a,node c,node d)
{
    node l,r;
    node mid,midmid;
    double l1,l2;
    l=c;
    r=d;
    while(dis(l,r)>=eps)
    {
        mid.x=(l.x+r.x)/2;
        mid.y=(l.y+r.y)/2;
        midmid.x=(mid.x+r.x)/2;
        midmid.y=(mid.y+r.y)/2;
        l1=dis(a,mid)/R+dis(mid,d)/v2;
        l2=dis(a,midmid)/R+dis(midmid,d)/v2;
        if(l1>l2)
            l=mid;
        else r=midmid;
    }
    return l1;
}

double cal(node a,node b,node c,node d)
{
    node l,r;
    node mid,midmid;
    double l1,l2;
    l=a;
    r=b;
    do
    {

        mid.x=(l.x+r.x)/2;
        mid.y=(l.y+r.y)/2;
        midmid.x=(mid.x+r.x)/2;
        midmid.y=(mid.y+r.y)/2;
        l1=dis(a,mid)/v1+tcal(mid,c,d);
        l2=dis(a,midmid)/v1+tcal(midmid,c,d);
        if(l1>l2)
            l=mid;
        else r=midmid;
    }while(dis(r,l)>=eps);
    return l1;

}

int main()
{
    node a,b,c,d;
    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",&v1,&v2,&R);
        printf("%.2lf\n",cal(a,b,c,d));
    }
    return 0;
}

 

posted @ 2012-09-05 18:00  'wind  阅读(343)  评论(0编辑  收藏  举报