Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3) D. Barcelonian Distance 几何代数(简单)
题意:给出一条直线 ax +by+c=0 给出两个整点 (x1,y1) (x2,y2) 只有在x,y坐标至少有一个整点的时 以及 给出的直线才有路径(也就是格子坐标图的线上)
问 两个整点所需要经过的最短距离
思路: 整点和整点之间的最短路径 要么 经过 直线 要么不经过直线 如果不经过直线,那么最短距离就是两者的曼哈顿距离 |x1-x2|+|y1-y2|
如果经过线段 那么一个点有两种到线段的方式 一种是和线段上的点x 相同 一个是和线段上的点y相同 2*2一共四种情况 全部算一遍取最小即可
还要考虑斜率等于0以及直线垂直x轴的情况
1 #include<bits/stdc++.h> 2 #define F first 3 #define S second 4 #define pii pair<int,int> 5 #define pb push_back 6 #define mkp make_pair 7 #define all(zzz) (zzz).being(),(zzz).end() 8 typedef long long ll; 9 using namespace std; 10 const int maxn=1e5+5; 11 double dist(double x1,double y1,double x2,double y2){ 12 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 13 } 14 int main(){ 15 ll a,b,c; 16 scanf("%lld%lld%lld",&a,&b,&c); 17 ll x1,y1,x2,y2; 18 scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2); 19 double ans=abs(x2-x1)+abs(y2-y1); 20 if(a!=0&&b!=0){ 21 double x3=x1; 22 double y3=1.0*(-c-a*x1)/b; 23 double y4=y1; 24 double x4=1.0*(-c-b*y1)/a; 25 double x5=x2; 26 double y5=1.0*(-c-a*x2)/b; 27 double y6=y2; 28 double x6=1.0*(-c-b*y2)/a; 29 ans=min(dist(x3,y3,x5,y5)+abs(y3-y1)+abs(y5-y2),ans); 30 ans=min(dist(x4,y4,x5,y5)+abs(x4-x1)+abs(y5-y2),ans); 31 ans=min(dist(x3,y3,x6,y6)+abs(y3-y1)+abs(x6-x2),ans); 32 ans=min(dist(x4,y4,x6,y6)+abs(x4-x1)+abs(x6-x2),ans); 33 } 34 else if(a==0&&b!=0){ 35 ans=min(ans,dist(x1,-c/b,x2,-c/b)+abs(-c/b-y1)+abs(-c/b-y2)); 36 } 37 else if(a!=0&&b==0){ 38 ans=min(ans,dist(-c/a,y1,-c/a,y2)+abs(-c/a-x1)+abs(-c/a-x2)); 39 } 40 printf("%.10lf\n",ans); 41 return 0; 42 }