CF1032D Solution
题解
可以分两类讨论\(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;
}