题解 T26167 【柠檬的垂线】

有一条线段 \(AB\)\(A\)\(B\) 均在格点上。平面内有一点 \(P\)\(P\) 也在格点上。过 \(P\) 点做 \(PM\) \(\perp\) \(AB\),垂足为点 \(M\) .求线段 \(PM\) 的长。

介绍一种数学方法。

\(A(x_A,y_A)\), \(B(x_B,y_B)\), \(P(x_P,y_P)\).

易求得直线 \(AB\) 直线方程

\[AB:y=\frac{y_A-y_B}{x_A-x_B} \cdot x + \frac{x_Ay_B-x_By_A}{x_A-x_B}\]

也可以求得直线 \(PM\) 直线方程

\[PM:y=-\frac{x_A-x_B}{y_A-y_B}\cdot x+\frac{x_A-x_B}{y_A-y_B} \cdot x_P+y_P\]

联立成为方程组,解得

\[x_M = \frac{(x_A-x_B)(x_Ax_P-x_Bx_P+y_Ay_P-y_By_P)-(y_A-y_B)(x_Ay_B-x_By_A)}{(x_A - x_B)^2+(y_A-y_B)^2}\]

\[y_M = \frac{x_P(x_A-x_B)(y_A-y_B)+(x_A-x_B)(x_Ay_B-x_By_A)+y_p(y_A-y_B)^2}{(x_A - x_B)^2+(y_A-y_B)^2}\]

所以可以将 \(M\) 坐标出来

\[M (\frac{(x_A-x_B)(x_Ax_P-x_Bx_P+y_Ay_P-y_By_P)-(y_A-y_B)(x_Ay_B-x_By_A)}{(x_A - x_B)^2+(y_A-y_B)^2}, \frac{x_P(x_A-x_B)(y_A-y_B)+(x_A-x_B)(x_Ay_B-x_By_A)+y_p(y_A-y_B)^2}{(x_A - x_B)^2+(y_A-y_B)^2})\]

那么最后两点间距离公式套一下就出来了。

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

double x_A, x_B, x_P, y_A, y_B, y_P;
double x_M, y_M;

int main()
{
    cin >> x_A >> y_A;
    cin >> x_B >> y_B;
    cin >> x_P >> y_P;
    x_M = ( ( x_A - x_B ) * ( x_A * x_P - x_B * x_P + y_A * y_P - y_B * y_P ) - ( y_A - y_B ) * ( x_A * y_B - x_B * y_A ) ) /
          ( ( x_A - x_B ) * ( x_A - x_B ) + ( y_A - y_B ) * ( y_A - y_B ) );
    y_M = ( x_P * ( x_A - x_B ) * ( y_A - y_B ) + ( x_A - x_B ) * ( x_A * y_B - x_B * y_A ) + ( y_A - y_B ) * ( y_A * y_P - y_B * y_P ) ) /
          ( ( x_A - x_B ) * ( x_A - x_B ) + ( y_A - y_B ) * ( y_A - y_B ) );
    //cout << x_M << " " << y_M << endl;
    cout << setiosflags( ios::fixed ) << setprecision( 0 ) << sqrt( ( x_P - x_M ) * ( x_P - x_M ) + ( y_P - y_M ) * ( y_P - y_M ) );
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tweetuzki/p/9274773.html