We all know that a pair of distinct points on a plane defines a line and that a pair of lines on a plane will intersect in one of three ways: 1) no intersection because they are parallel, 2) intersect in a line because they are on top of one another (i.e. they are the same line), 3) intersect in a point. In this problem you will use your algebraic knowledge to create a program that determines how and where two lines intersect.
Your program will repeatedly read in four points that define two lines in the x-y plane and determine how and where the lines intersect. All numbers required by this problem will be reasonable, say between -1000 and 1000.
Input
Output
Sample Input
5 0 0 4 4 0 4 4 0 5 0 7 6 1 0 2 3 5 0 7 6 3 -6 4 -3 2 0 2 27 1 5 18 5 0 3 4 0 1 2 2 5
Sample Output
INTERSECTING LINES OUTPUT POINT 2.00 2.00 NONE LINE POINT 2.00 5.00 POINT 1.07 2.20 END OF OUTPUT
很简单直接暴力分类,类别也不是很多,有一个坑点就是double型的0乘负数会变成负0,太坑了!!
这里放一下测试代码
#include<map> #include<set> #include<list> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 using namespace std; const int N=100005,maxn=100005,inf=0x3f3f3f3f3f; int main() { double x=0.0,y=x*(-1); printf("%.2f\n",y); if(y==0)y=fabs(y); printf("%.2f\n",y); return 0; }
#include<map> #include<set> #include<list> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 using namespace std; const double eps=1e-8; const int N=5,maxn=100005,inf=0x3f3f3f3f; struct point{ int x,y; }; struct line{ point a,b; }l[N]; int main() { int t; double x1,y1,x2,y2,x3,y3,x4,y4; cin>>t; cout<<"INTERSECTING LINES OUTPUT"<<endl; while(t--){ cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4; if((y4-y3)*(x2-x1)==(y2-y1)*(x4-x3)) { if((y3-y1)*(x2-x1)!=(y2-y1)*(x3-x1)) cout<<"NONE"<<endl; else cout<<"LINE"<<endl; } else { double x,y; if(x2==x1) { x=x1; y=y3+(x-x3)*(y4-y3)/(x4-x3); } else if(x3==x4) { x=x3; y=y1+(x-x1)*(y2-y1)/(x2-x1); } else { x=(y3-y1+x1*(y2-y1)/(x2-x1)-x3*(y4-y3)/(x4-x3))/((y2-y1)/(x2-x1)-(y4-y3)/(x4-x3)); y=(x-x1)*(y2-y1)/(x2-x1)+y1; } if(x==0)x=fabs(x); if(y==0)y=fabs(y); printf("POINT %.2f %.2f\n",x,y); } } cout<<"END OF OUTPUT"<<endl; return 0; }
又看了一下网上的题解发现有更简单的叉积判断
首先判断斜率是非相同还是用公式直接来(x4-x3)*(y2-y1)==(y4-y3)*(x2-x1)
然后用叉积(x2-x1)*(y3-y1)==(y2-y1)*(x3-x1)判断x3是不是在x1,x2这条线上是的话就是LINE,否则就是NONE
最后叉积计算交点:
设交点(x0,y0)
(x2-x1)*(y0-y1)-(y2-y1)*(x0-x1)=0;
(x4-x3)*(y0-y3)-(y4-y3)*(x0-x3)=0;
化简可得:
(y1-y2)*x0+(x2-x1)*y0+x1*y2-x2*y1=0;
(y3-y4)*x0+(x4-x3)*y0+x3*y4-x4*y3=0;
建立二元一次方程:
a1*x0+b1*y0+c1=0;
a2*x0+b2*y0+c2=0;
解得:
x0=(c2*b1-c1*b2)/(b2*a1-b1*a2);
y0=(a2*c1-a1*c2)/(b2*a1-b1*a2);
带入就好了,以下是新方法 的ac代码:
#include<map> #include<set> #include<list> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 using namespace std; const double eps=1e-8; const int N=5,maxn=100005,inf=0x3f3f3f3f; struct point{ double x,y; }; struct line{ point a,b; }l[N]; int main() { int t; double x1,x2,x3,x4,y1,y2,y3,y4; cin>>t; cout<<"INTERSECTING LINES OUTPUT"<<endl; while(t--){ cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4; if((x4-x3)*(y2-y1)==(y4-y3)*(x2-x1))//斜率判断 { if((x2-x1)*(y3-y1)==(y2-y1)*(x3-x1))cout<<"LINE"<<endl;//用叉积判断共线 else cout<<"NONE"<<endl; } else { double a1=y1-y2,b1=x2-x1,c1=x1*y2-x2*y1; double a2=y3-y4,b2=x4-x3,c2=x3*y4-x4*y3; double x=(c2*b1-c1*b2)/(b2*a1-b1*a2); double y=(a2*c1-a1*c2)/(b2*a1-b1*a2); printf("POINT %.2f %.2f\n",x,y); } } cout<<"END OF OUTPUT"<<endl; return 0; }