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; }