Orz,原来是三分大法,还以为有公式,但是推不出来
据说耗费时间是一个二次函数
设在线段AB上取点(x1,y1),CD上取点(x2,y2);
点A坐标为(ax,ay),点D坐标为(dx,dy)
那么时间就是sqrt((ax-x1)^2+(ay-y1)^2)/p同理,可以发现是二次函数
然后三分在AB上的点,和在CD上的点求出答案即可
下面是代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const double eps=1e-3;
int ax,ay,bx,by,cx,cy,dx,dy,p,q,r;
double ans;
double dis(double x,double y,double x1,double y1){
double v1=sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
return v1;
}
double work(double sx,double sy,double x,double y){
double res=dis(ax,ay,sx,sy)/p+dis(sx,sy,x,y)/r+dis(x,y,dx,dy)/q;
return res;
}
double calc(double sx,double sy){
double lx=cx,ly=cy,rx=dx,ry=dy;
while(fabs(lx-rx)>eps||fabs(ly-ry)>eps){
double x1=lx+(rx-lx)/3;
double y1=ly+(ry-ly)/3;
double x2=lx+(rx-lx)/3*2;
double y2=ly+(ry-ly)/3*2;
if(work(sx,sy,x1,y1)>work(sx,sy,x2,y2)){
lx=x1;ly=y1;
}else{
rx=x2;ry=y2;
}
}
return work(sx,sy,lx,ly);
}
int main(){
cin>>ax>>ay>>bx>>by>>cx>>cy>>dx>>dy>>p>>q>>r;
double lx=ax,ly=ay,rx=bx,ry=by;
while(fabs(lx-rx)>eps||fabs(ly-ry)>eps){
double x1=lx+(rx-lx)/3;
double y1=ly+(ry-ly)/3;
double x2=lx+(rx-lx)/3*2;
double y2=ly+(ry-ly)/3*2;
if(calc(x1,y1)>calc(x2,y2)){
lx=x1;
ly=y1;
}else{
rx=x2;
ry=y2;
}
}
ans=min(calc(lx,ly),calc(rx,ry));
printf("%.2lf\n",ans);
return 0;
}