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

 

 

 

posted @ 2013-08-03 12:21  _随心所欲_  阅读(349)  评论(0编辑  收藏  举报