[BZOJ1857] conveyor belt (three points)

Problem surface

Description

There are two conveyor belts on A 2D plane, each belt can be regarded as A line segment. The two belts are line AB and line CD. The moving speed of lxhgww is P on AB, Q on CD and R on plane. Now lxhgww wants to go from point A to point D, and he wants to know how long it will take at least

Input

The first line of input data is 4 integers, representing the coordinates of A and B, respectively Ax, Ay, Bx, By the second line is 4 integers, representing the coordinates of C and D, respectively Cx, Cy, Dx, Dy the third line is 3 integers, respectively P, Q, R

Output

The output data is one line, indicating the shortest time from point A to point D of lxhgww, which is reserved to two decimal places

Sample Input

0 0 0 100

100 0 100 100

2 2 1

Sample Output

136.60

HINT

For 100% data, 1 < = ax, Ay, Bx, By, Cx, Cy, Dx, Dy < = 1000
1<=P,Q,R<=10

Title Solution

Another interesting topic
Now it's equivalent to asking for the minimum value of a function
Naturally, YY is a lower convex function
And then we will find out the answer at a third point on the AB line
How does the answer work? Naturally, find a point on the CD line first, and then calculate it.
Continue YY. This is also a lower convex function
So again, three points
And then the honey is done.
However, this question is also very confusing. Please use do while for three points
Otherwise, there will be strange data, because the dots are close together
Three points failed

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define esp 1e-5
inline int read()
{
    int x=0,t=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
double A1,B1,A2,B2,Lx,Rx,Ly,Ry;
double Ax,Ay,Bx,By,Cx,Cy,Dx,Dy;
double P,Q,RR;
double Dis(double x,double y,double X,double Y)
{
    return sqrt((x-X)*(x-X)+(y-Y)*(y-Y));
}
double Count(double xx,double yy)
{
    double lx=Cx,rx=Dx;
    double ly=Cy,ry=Dy;
    double ret=0;
    do
    {
        double m1=(rx-lx)/3+lx,z1=(ry-ly)/3+ly;
        double m2=lx+rx-m1,z2=ly+ry-z1;
        double tt1=Dis(Ax,Ay,xx,yy)/P+Dis(xx,yy,m1,z1)/RR+Dis(m1,z1,Dx,Dy)/Q;
        double tt2=Dis(Ax,Ay,xx,yy)/P+Dis(xx,yy,m2,z2)/RR+Dis(m2,z2,Dx,Dy)/Q;
        if(tt1>tt2)lx=m1,ly=z1,ret=tt2;
        else rx=m2,ry=z2,ret=tt1;
    }while(fabs(lx-rx)>esp||fabs(ly-ry)>esp);
    return ret;
}
int main()
{
    Ax=read();Ay=read();Bx=read();By=read();
    Cx=read();Cy=read();Dx=read();Dy=read();
    P=read();Q=read();RR=read();
    Lx=Ax,Rx=Bx;
    Ly=Ay,Ry=By;
    double ans=0;
    do
    {
        double mx1=(Rx-Lx)/3+Lx,my1=(Ry-Ly)/3+Ly;
        double mx2=Lx+Rx-mx1,my2=Ly+Ry-my1;
        double k1=Count(mx1,my1),k2=Count(mx2,my2);
        if(k1>k2)Lx=mx1,Ly=my1,ans=k1;
        else Rx=mx2,Ry=my2,ans=k2;
    }while(fabs(Rx-Lx)>esp||fabs(Ry-Ly)>esp);
    printf("%.2lf\n",ans);
    return 0;
}

Posted on Mon, 04 May 2020 01:25:23 -0400 by FezEvils