题解
可以分两类讨论(A,B)点间的最短路径,经过函数与不经过函数,其中不经过函数的情况曼哈顿距离即可。
可得在只能经过格点的情况下,点(A)到函数(f)最短距离的点(x)值与(y)值中一定有一项与(A)相等。
也就是如左图,点(A)到直线的最短距离一定为(AD)与(AC)的最小值,(B)同理。
感谢机房神仙提供的证明!(。・∀・)ノ:
当斜率(>1)时右下((x)相等时)同理。
因此经过函数的情况只需枚举上图中的(C,D,E,F),排列组合取最小值即可。
AC代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
double a,b,c,xa,xb,ya,yb;
scanf("%lf%lf%lf%lf%lf%lf%lf",&a,&b,&c,&xa,&ya,&xb,&yb);
double ans1=abs(xa-xb)+abs(ya-yb),ans2;
//ans1:曼哈顿距离,ans2:经过函数的最短距离
double tx1=-(b*ya+c)/a,ty1=-(a*xa+c)/b,tx2=-(b*yb+c)/a,ty2=-(a*xb+c)/b;
//tx1:C的x值,ty1:D的y值,tx2:E的x值,ty2:F的y值
//经过CF的情况
ans2=abs(tx1-xa)+sqrt((tx1-xb)*(tx1-xb)+(ty2-ya)*(ty2-ya))+abs(ty2-yb);
//经过DE的情况
ans2=min(ans2,abs(tx2-xb)+sqrt((tx2-xa)*(tx2-xa)+(ty1-yb)*(ty1-yb))+abs(ty1-ya));
//经过CE的情况
ans2=min(ans2,abs(tx1-xa)+sqrt((tx1-tx2)*(tx1-tx2)+(ya-yb)*(ya-yb))+abs(tx2-xb));
//经过DF的情况
ans2=min(ans2,abs(ty1-ya)+sqrt((ty1-ty2)*(ty1-ty2)+(xa-xb)*(xa-xb))+abs(ty2-yb));
printf("%lf",min(ans1,ans2));
return 0;
}