HDU-3400-(三分套三分)

博客给出一道题目,包含Sample Input和Sample Output。题意是给定两条线段AB和CD,一人在AB上速度为P,CD上速度为Q,其他地方速度为R,要求从A到D的最少时间,但作者未阐述解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目
在这里插入图片描述在这里插入图片描述
Sample Input
1
0 0 0 100
100 0 100 100
2 2 1

Sample Output
136.60

题意:
给你两条线段AB , CD ,有一个人在AB以速度P跑,在CD上以Q跑,在其他地方跑速度是R。求从A到D最少的时间。
思路:不想说了。。T_T

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#define m(a,b) memset(a,b,sizeof a)
#define en '\n'
#define eps 1e-6
using namespace std;
typedef double du;
const int INF=0x3f3f3f3f,N=13+2;
du P,Q,R;
struct Point{du x,y;}A,B,C,D;
du po_dis(Point &a,Point &b)
{
    return sqrt(eps+(b.y-a.y)*(b.y-a.y)+(b.x-a.x)*(b.x-a.x));
}
du walk_CD(du &s,Point &E)
{
    du lcd=po_dis(C,D);
    Point F=(Point){C.x+s/lcd*(D.x-C.x),C.y+s/lcd*(D.y-C.y)};//AE
    return po_dis(E,F)/R+po_dis(F,D)/Q;//EF+FD.
}
du walk_AB(du &d)
{
    du lab=po_dis(A,B);
    Point E=(Point){A.x+d/lab*(B.x-A.x),A.y+d/lab*(B.y-A.y)};//AE
    du t=d/P;//AE花费的时间.
    if(Q<=R) //根据两边之差小于第三边 这个可以直接得出结论,E直接走到D点费时最少。
        return t+po_dis(E,D)/R;//AE+ED花费的时间.
    else
    {
        du l=0.0,r=po_dis(C,D),m1,m2,ans;
        while(fabs(r-l)>eps)//三分从哪个点到CD的(F点)。也是同理不应三分沿x轴方向走了多少。
        {
            m1=l+(r-l)/3.0,m2=r-(r-l)/3.0;
            if(walk_CD(m1,E)>(ans=walk_CD(m2,E)))
                l=m1;
            else
                r=m2;
        }
        return t+ans;
    }
}
int main()
{
    int T;scanf("%d",&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("%lf%lf%lf",&P,&Q,&R);
        du l=0.0,r=po_dis(A,B),m1,m2,ans;
        while(fabs(r-l)>eps)//三分在AB上走的距离AE。由于可能AB可能垂直x轴,不应三分三分沿x轴方向走了多少,应三分沿AB走了多少.
        {
            m1=l+(r-l)/3.0,m2=r-(r-l)/3.0;
            if(walk_AB(m1)>(ans=walk_AB(m2)))
                l=m1;
            else
                r=m2;
        }
        printf("%.2f\n",ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值