1 题意
判断两条直线是否平行,重合或相交,如果相交则输出交点坐标。
链接:link。
2 思路
命题1:向量
a
⃗
,
b
⃗
\vec a,\vec b
a,b平行的充要条件为
a
⃗
×
b
⃗
=
0
\vec a \times \vec b = 0
a×b=0。
证明:
先证必要性,已知
a
⃗
×
b
⃗
=
∣
a
⃗
∣
∣
b
⃗
∣
sin
<
a
⃗
,
b
⃗
>
=
0
\vec a \times \vec b = \left|\vec a \right|\left|\vec b\right| \sin<\vec a,\vec b>=0
a×b=∣a∣∣∣∣b∣∣∣sin<a,b>=0。
1. 若
∣
a
⃗
∣
=
0
\left|\vec a \right|=0
∣a∣=0或
∣
b
⃗
∣
=
0
\left|\vec b \right|=0
∣∣∣b∣∣∣=0,则说明
a
⃗
\vec a
a或
b
⃗
\vec b
b为零向量,由零向量与任何向量平行,可知
a
⃗
/
/
b
⃗
\vec a // \vec b
a//b。
2. 若
sin
<
a
⃗
,
b
⃗
>
=
0
\sin<\vec a,\vec b>=0
sin<a,b>=0,则说明
<
a
⃗
,
b
⃗
>
=
π
<\vec a,\vec b>=\pi
<a,b>=π或
<
a
⃗
,
b
⃗
>
=
2
π
<\vec a,\vec b>=2\pi
<a,b>=2π,显然两个向量平行。
再证必要性,若向量
a
⃗
,
b
⃗
\vec a,\vec b
a,b平行,则说明
<
a
⃗
,
b
⃗
>
=
π
<\vec a,\vec b>=\pi
<a,b>=π或
<
a
⃗
,
b
⃗
>
=
2
π
<\vec a,\vec b>=2\pi
<a,b>=2π,那么
sin
<
a
⃗
,
b
⃗
>
=
0
\sin<\vec a,\vec b>=0
sin<a,b>=0,即
a
⃗
×
b
⃗
=
0
\vec a \times \vec b = 0
a×b=0,得证。
命题2:两条直线平行或重合的充要条件是其方向向量的向量积为0。
证明:略。
命题3:假设两条直线
l
1
,
l
2
l_{1},l_{2}
l1,l2的方向向量分别为
P
1
P
2
→
,
P
3
P
4
→
\overrightarrow{P_{1}P_{2}},\overrightarrow{P_{3}P_{4}}
P1P2,P3P4,且两条直线平行或重合,即
P
1
P
2
→
×
P
3
P
4
→
=
0
\overrightarrow{P_{1}P_{2}} \times \overrightarrow{P_{3}P_{4}}=0
P1P2×P3P4=0。如果
P
1
P
4
→
×
P
3
P
2
→
=
0
\overrightarrow{P_{1}P_{4}} \times \overrightarrow{P_{3}P_{2}}=0
P1P4×P3P2=0,则两条直线重合,否则两条直线平行。
证明:略。
命题3:假设两条直线 l 1 , l 2 l_{1},l_{2} l1,l2相交,且其方向向量分别为 P 1 P 2 → , P 3 P 4 → \overrightarrow{P_{1}P_{2}},\overrightarrow{P_{3}P_{4}} P1P2,P3P4,其中 P 1 = ( x 1 , y 1 ) , P 2 = ( x 2 , y 2 ) , P 3 = ( x 3 , y 3 ) , P 4 = ( x 4 , y 4 ) P_{1}=(x_{1},y_{1}),P_{2}=(x_{2},y_{2}),P_{3}=(x_{3},y_{3}),P_{4}=(x_{4},y_{4}) P1=(x1,y1),P2=(x2,y2),P3=(x3,y3),P4=(x4,y4),则两条直线的交点为 ( ( x 1 y 2 − x 2 y 1 ) ( x 4 − x 3 ) − ( x 3 y 4 − x 4 y 3 ) ( x 2 − x 1 ) ( y 2 − y 1 ) ( x 4 − x 3 ) − ( y 4 − y 3 ) ( x 2 − x 1 ) , ( y 2 − y 1 ) ( x 3 y 4 − x 4 y 3 ) − ( y 4 − y 3 ) ( x 1 y 2 − x 2 y 1 ) ( x 2 − x 1 ) ( y 4 − y 3 ) − ( x 4 − x 3 ) ( y 2 − y 1 ) ) \Big(\frac{(x_{1}y_{2}-x_{2}y_{1})(x_{4}-x_{3})-(x_{3}y_{4}-x_{4}y_{3})(x_{2}-x_{1})}{(y_{2}-y_{1})(x_{4}-x_{3})-(y_{4}-y_{3})(x_{2}-x_{1})},\frac{(y_{2}-y_{1})(x_{3}y_{4}-x_{4}y_{3})-(y_{4}-y_{3})(x_{1}y_{2}-x_{2}y_{1})}{(x_{2}-x_{1})(y_{4}-y_{3})-(x_{4}-x_{3})(y_{2}-y_{1})}\Big) ((y2−y1)(x4−x3)−(y4−y3)(x2−x1)(x1y2−x2y1)(x4−x3)−(x3y4−x4y3)(x2−x1),(x2−x1)(y4−y3)−(x4−x3)(y2−y1)(y2−y1)(x3y4−x4y3)−(y4−y3)(x1y2−x2y1))。
2.1 时间复杂度分析
判断直线是否平行或相交的时间复杂度为 O ( 1 ) \mathcal{O}(1) O(1),计算交点坐标的时间复杂度为 O ( 1 ) \mathcal{O}(1) O(1),所以总的时间复杂度为 O ( 1 ) \mathcal{O}(1) O(1)。
2.2 实现
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int T;scanf("%d",&T);
puts("INTERSECTING LINES OUTPUT");
while(T--){
double x1,y1,x2,y2,x3,y3,x4,y4;
scanf("%lf %lf %lf %lf %lf %lf %lf %lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
if((x2-x1)*(y4-y3)==(x4-x3)*(y2-y1)){
if((x3-x1)*(y2-y1)==(x2-x1)*(y3-y1)) puts("LINE");
else puts("NONE");
}else{
double a1=y2-y1,b1=x2-x1,c1=x1*y2-x2*y1;
double a2=y4-y3,b2=x4-x3,c2=x3*y4-x4*y3;
printf("POINT %.2lf %.2lf\n",(c1*b2-c2*b1)/(a1*b2-a2*b1),(a1*c2-a2*c1)/(b1*a2-b2*a1));
}
}
cout<<"END OF OUTPUT"<<endl;
return 0;
}