P2571 [SCOI2010]传送带

传送门

然后要注意细节和精度问题(要注意A,B或C,D在同一点的可能,导致三分还没开始就结束了)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=0.00001;
double Ax,Ay,Bx,By,Cx,Cy,Dx,Dy,P,Q,R;
inline double f(double ex,double ey,double fx,double fy)
{
    double AE=sqrt( (Ax-ex)*(Ax-ex) + (Ay-ey)*(Ay-ey) )/P;
    double EF=sqrt( (ex-fx)*(ex-fx) + (ey-fy)*(ey-fy) )/R;
    double FD=sqrt( (fx-Dx)*(fx-Dx) + (fy-Dy)*(fy-Dy) )/Q;
    return AE+EF+FD;
}//当E,F点确定时,求出AE+EF+FD的时间(注意是时间)
inline double narrow(double x,double y)
{
    double cx=Cx,dx=Dx,cy=Cy,dy=Dy,mi=0;
    do
    {
        double midx=(cx+dx)/2,midy=(cy+dy)/2;
        double ans1=f(x,y,midx,midy),ans2=f(x,y,(midx+dx)/2,(midy+dy)/2);

        if(ans1>ans2) cx=midx,cy=midy;
        else dx=(midx+dx)/2,dy=(midy+dy)/2;

        mi=min(ans1,ans2);
    }while(fabs(cx-dx)>=eps||fabs(cy-dy)>=eps);
    //注意循环是do while(防止三分还没开始就结束导致答案为0)
    return mi;
}//当E点确定时求出AE+EF+FD的时间的最小值
int main()
{
    cin>>Ax>>Ay>>Bx>>By;
    cin>>Cx>>Cy>>Dx>>Dy;
    cin>>P>>Q>>R;
    double ax=Ax,bx=Bx,ay=Ay,by=By,mi=0;
    do
    {
        double midx=(ax+bx)/2,midy=(ay+by)/2;
        double ans1=narrow(midx,midy),ans2=narrow((midx+bx)/2,(midy+by)/2);

        if(ans1>ans2) ax=midx,ay=midy;
        else bx=(midx+bx)/2,by=(midy+by)/2;

        mi=min(ans1,ans2);

    }while(fabs(ax-bx)>=eps||fabs(ay-by)>=eps);
     //注意循环是do while(防止三分还没开始就结束导致答案为0)
    printf("%.2f",mi);
    return 0;
}
原文地址:https://www.cnblogs.com/LLTYYC/p/9612497.html