hdu 3400 Line belt 三分法

思路:要求最短时间从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\n",ans);

    }

    return 0;

}
View Code

 

 

 

你可能感兴趣的:(HDU)