【BZOJ 1857】 [Scoi2010]传送带

1857: [Scoi2010]传送带

Time Limit: 1 Sec Memory Limit: 64 MB
Submit: 737 Solved: 387
[Submit][Status][Discuss]
Description

在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间
Input

输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 第三行是3个整数,分别是P,Q,R
Output

输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留到小数点后2位
Sample Input

0 0 0 100

100 0 100 100

2 2 1

Sample Output

136.60

HINT

对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10
Source

Day2

三分套三分。

首先如果确定了AB上从哪个点离开,那么CD上点的距离函数一定是一个单谷函数,可以三分来求。

如何求解AB上的点呢?

他也满足单谷的性质(然而并不会证明),可以三分来求。

所以就是三分套三分了。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define eps 1e-5
using namespace std;
struct Point
{
    double x,y;
    friend Point operator +(Point a,Point b)
    {
        return (Point){a.x+b.x,a.y+b.y};
    }
    friend Point operator -(Point a,Point b)
    {
        return (Point){a.x-b.x,a.y-b.y};
    }
    friend Point operator /(Point a,int k)
    {
        return (Point){(double)a.x/k,(double)a.y/k};
    }
}a,b,c,d;
double P,Q,R;
double Sqr(double x)
{
    return x*x;
}
double Dis(Point x,Point y)
{
    return sqrt(Sqr(x.x-y.x)+Sqr(x.y-y.y));
}
double Get(Point ab,Point cd)
{
    return Dis(a,ab)/P+Dis(ab,cd)/R+Dis(cd,d)/Q;
}
double Calc(Point x)
{
    Point l=c,r=d;
    while (fabs(l.x-r.x)>eps||fabs(l.y-r.y)>eps)
    {
        Point m=l+(r-l)/3,mm=r-(r-l)/3;
        double am=Get(x,m),amm=Get(x,mm);
        if (am<amm) r=mm;
        else l=m;
    }
    return Get(x,l);
}
int main()
{
    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",&P,&Q,&R);
    Point l=a,r=b;
    while (fabs(l.x-r.x)>eps||fabs(l.y-r.y)>eps)
    {
        Point m=l+(r-l)/3,mm=r-(r-l)/3;
        double am=Calc(m),amm=Calc(mm);
        if (am<amm)
            r=mm;
        else l=m;
    }
    printf("%.2lf\n",Calc(l));
    return 0;
}

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值