BZOJ1857:[SCOI2010]传送带——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=1857

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

——————————————————————————————

首先我们取AB一点E,CD一点F,则我们跑了AE+EF+FD。

考虑将其中一个点固定住,那么显然对于另一个点我们三分即可求出这个店的位置(显然该点有最小值,他的左右两点都比他大,所以为单峰函数)。

那么对于最开始的点,我们同样也是单峰函数,也可以三分(通过神奇的代数几何可以证明)

所以这题就是三分套三分。

PS:因为这题x1与x2可能相同,所以不能单独三分x或y,必须同时三分(不然代码量太大了)

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
typedef double dl;
const int N=100;
dl ax,ay,bx,by,cx,cy,dx,dy,P,Q,R;
inline dl dis(dl x,dl y,dl xx,dl yy){
    return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
}
dl sff(dl x,dl y){
    dl lx=cx,rx=dx,ly=cy,ry=dy;
    dl lfx,lfy,rfx,rfy;
    for(int i=1;i<=N;i++){
    lfx=(lx*2+rx)/3;lfy=(ly*2+ry)/3;
    rfx=(lfx+rx)/2;rfy=(lfy+ry)/2;
    dl t1=dis(lfx,lfy,dx,dy)/Q+dis(lfx,lfy,x,y)/R;
    dl t2=dis(rfx,rfy,dx,dy)/Q+dis(rfx,rfy,x,y)/R;
    if(t1<t2){
        rx=rfx;ry=rfy;
    }else{
        lx=lfx;ly=lfy;
    }
    }
    return dis(lx,ly,dx,dy)/Q+dis(lx,ly,x,y)/R+dis(x,y,ax,ay)/P;
}
dl sfe(dl lx,dl rx,dl ly,dl ry){
    dl lex,ley,rex,rey;
    for(int i=1;i<=N;i++){
    lex=(lx*2+rx)/3;ley=(ly*2+ry)/3;
    rex=(lex+rx)/2;rey=(ley+ry)/2;
    if(sff(lex,ley)<sff(rex,rey)){
        rx=rex;ry=rey;
    }else{
        lx=lex;ly=ley;
    }
    }
    return sff(lx,ly);
}
int main(){
    cin>>ax>>ay>>bx>>by>>cx>>cy>>dx>>dy>>P>>Q>>R;
    printf("%.2lf\n",sfe(ax,bx,ay,by));
    return 0;
}

 

posted @ 2017-12-08 20:32  luyouqi233  阅读(494)  评论(0编辑  收藏  举报