HDU 3400 三分

题意:给出 两条线段 AB   CD 算出 A到D的最短时间  

思路: 一步一步来 ,先利用三分 确定AB中的点,然后在三分CD中的点 最后求出最短时间

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

struct point{
    
    double x,y;
    point (){}
    point (double x,double y):x(x),y(y) {}
    point operator * (int a){
        return point (x*a,y*a);
    }
    point operator / (int a){
        return point(x/a,y/a);
    }
    point operator + (point a){
        return point (x+a.x,y+a.y);
    }
    point operator - (point a){
        return point (x-a.x,y-a.y);
    }
    
};

point a,b,c,d;int p,q,rrr;
const double EPS=1e-9;

double dis(point e,point f){
    return sqrt((e.x-f.x)*(e.x-f.x)+(e.y-f.y)*(e.y-f.y));
}

double solve(point l,point r){
    return dis(l,a)/p+dis(l,r)/rrr+dis(r,d)/q;
}

double ternarySearch1(point l,point r,point k)
{
    double ans=1e8;
    do
    {
        point ll=((l*2)+r)/3;
        point rr=(l+(r*2))/3;
        double ans1=solve(k,ll);
        double ans2=solve(k,rr);
        ans=min(ans1,ans2);
        if(ans1>ans2)
            l=ll;
        else
            r=rr;
    }while(dis(r,l)>EPS);
    return ans;
}

double ternarySearch(point l,point r)
{
    double ans=1e8;
    do
    {
        point ll=((l*2)+r)/3;
        point rr=(l+(r*2))/3;
        double ans1=ternarySearch1(c,d,ll);
        double ans2=ternarySearch1(c,d,rr);
        ans=min(ans1,ans2);
        if(ans1>ans2)
            l=ll;
        else
            r=rr;
        // cout<<ans<<endl;
    }while(dis(r,l)>EPS);
    return ans;
}

int main(int argc, const char * argv[]) {
    int t;
    cin>>t;
    while (t--) {
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
        scanf("%d%d%d",&p,&q,&rrr);
        printf("%.2lf\n",ternarySearch(a,b));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值