看到这题第一感觉暴力呀233
然后就乱搞水过了(数据太水?)
我的做法是将AB,CD分别等分为512段
这样AB,CD上各有513个顶点,不妨设AB上的顶点为E,CD上的顶点为F
通过数学容易得到A到D的最短时间移动路径是AE-EF-FD,
那枚举E在AB上那513个顶点位置,枚举F在CD上那513个顶点位置,
其中满足AE/P+FD/Q+EF/R最小的E,F点时路径移动时间最短,此时AE/P+FD/Q+EF/R就是答案
由于线段长度有限,取512段基本可以满足精度问题
听神犇说这题是三分?我表示一脸懵逼2333
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
int ax,ay,bx,by,cx,cy,dx,dy;
int p,q,r;
int tza=0,tzb=0;
double ka,kb,ba,bb;
double sum=0,ans=0x3f3f3f3f;
struct data{
double xi,yi;
}op[2005],kp[2005];
int cnt=2,tot=2;
void find(double axx,double ayy,double bxx,double byy,int timm)
{
if(timm>8)return ;
double oxx,oyy;
oxx=(axx+bxx)/2.0;
oyy=(ayy+byy)/2.0;
cnt++;
op[cnt].xi=oxx;
op[cnt].yi=oyy;
find(axx,ayy,oxx,oyy,timm+1);
find(oxx,oyy,bxx,byy,timm+1);
}
void seach(double axx,double ayy,double bxx,double byy,int timm)
{
if(timm>8)return ;
double oxx,oyy;
oxx=(axx+bxx)/2.0;
oyy=(ayy+byy)/2.0;
tot++;
kp[tot].xi=oxx;
kp[tot].yi=oyy;
seach(axx,ayy,oxx,oyy,timm+1);
seach(oxx,oyy,bxx,byy,timm+1);
}
void lcr(int x,int y)
{
double lena,lenb,lenc;
lena=sqrt((kp[x].xi-ax)*(kp[x].xi-ax)+(kp[x].yi-ay)*(kp[x].yi-ay));
lena/=(double)p;
lenb=sqrt((op[y].xi-dx)*(op[y].xi-dx)+(op[y].yi-dy)*(op[y].yi-dy));
lenb/=(double)q;
lenc=sqrt((kp[x].xi-op[y].xi)*(kp[x].xi-op[y].xi)+(kp[x].yi-op[y].yi)*(kp[x].yi-op[y].yi));
lenc/=(double)r;
sum=(lena+lenb+lenc);
ans=min(sum,ans);
}
int main()
{
int i,j,k,l;
scanf("%d%d%d%d",&ax,&ay,&bx,&by);
scanf("%d%d%d%d",&cx,&cy,&dx,&dy);
scanf("%d%d%d",&p,&q,&r);
op[1].xi=cx;op[1].yi=cy;
op[2].xi=dx;op[2].yi=dy;
find(cx,cy,dx,dy,0);
kp[1].xi=ax;kp[1].yi=ay;
kp[2].xi=bx;kp[2].yi=by;
seach(ax,ay,bx,by,0);
for(i=1;i<=tot;i++){
for(j=1;j<=cnt;j++){
lcr(i,j);
}
}
printf("%.2lf",ans);
return 0;
}