题目连接:http://codeforces.com/contest/1032/problem/D
题解:可以很直观的想象,如果加上直线后能让距离变短的话,那么直线应该和A、B两点构成的矩形相交,所以计算出直线与矩形的交点后算距离求一个最小值就可以了。直线与坐标轴平行的话可以不用管交点。
代码:
#include<bits/stdc++.h> using namespace std; struct Point{ double x, y; }; double mhd(Point a, Point b){//曼哈顿距离 return abs(a.x-b.x) + abs(a.y-b.y); } double dis(Point a, Point b){//欧几里得距离 return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } int main(){ double a, b, c; cin >> a >> b >> c; Point A, B, p, q; cin >> A.x >> A.y >> B.x >> B.y; double tx, ty, ans = mhd(A, B);//初始化答案为A到B的曼哈顿距离 bool flag1 = 0, flag2 = 0; if(b != 0 && a != 0){ tx = A.x; ty = (-a*tx-c)/b; if(ty >= min(A.y, B.y) && ty <= max(A.y, B.y)){ if(!flag1){ p.x = tx; p.y = ty; flag1 = 1; } else if(!flag2){ q.x = tx; q.y = ty; flag2 = 1; } } tx = B.x; ty = (-a*tx-c)/b; if(ty >= min(A.y, B.y) && ty <= max(A.y, B.y)){ if(!flag1){ p.x = tx; p.y = ty; flag1 = 1; } else if(!flag2){ q.x = tx; q.y = ty; flag2 = 1; } } ty = B.y; tx = (-b*ty-c)/a; if(tx >= min(A.x, B.x) && tx <= max(A.x, B.x)){ if(!flag1){ p.x = tx; p.y = ty; flag1 = 1; } else if(!flag2){ q.x = tx; q.y = ty; flag2 = 1; } } ty = A.y; tx = (-b*ty-c)/a; if(tx >= min(A.x, B.x) && tx <= max(A.x, B.x)){ if(!flag1){ p.x = tx; p.y = ty; flag1 = 1; } else if(!flag2){ q.x = tx; q.y = ty; flag2 = 1; } } //以上是计算直线与矩形的交点,可以保证有两个交点 double d = dis(p, q); ans = min(ans, d + mhd(A, p) + mhd(q, B)); ans = min(ans, d + mhd(A, q) + mhd(p, B)); //取一个最小值 } printf("%.12f\n", ans); return 0; }