写得很复杂,还好一遍过了。
方法是直接根据线段两点,得到直线方程,联立方程组求交点,然后看交点是否在两线段之间。注意平行、位于同一直线时的情况就可以了。
#include<bits/stdc++.h> using namespace std; #define LL long long struct P { double x,y; }; int cmp(double x) { if(fabs(x)<1e-15) return 0; if(x>0) return 1; return -1; } bool get(P a1,P b1,double &k,double &b)//求直线方程 { if(cmp(a1.x-b1.x)==0) return 0;//垂直x轴 k=(a1.y-b1.y)/(a1.x-b1.x); b=a1.y-k*a1.x; return 1; } bool judge(P a1,P b1,P a2,P b2) { double k1,m1,k2,m2; if(!get(a1,b1,k1,m1)) { if(!get(a2,b2,k2,m2)) //均垂直x轴 { if(cmp(a1.x-a2.x)!=0) return 0; //平行 double max1=max(a1.y,b1.y),max2=max(a2.y,b2.y); double min1=min(a1.y,b1.y),min2=min(a2.y,b2.y); if(cmp(max2-min1)>=0&&cmp(max1-max2)>=0) return 1; if(cmp(max1-min2)>=0&&cmp(max2-max1)>=0) return 1; return 0; } else { double max2=max(a2.x,b2.x),min2=min(a2.x,b2.x); double maxy=max(a1.y,b1.y),miny=min(a1.y,b1.y); if(cmp(a1.x-min2)>=0&&cmp(a1.x-max2)<=0) { double ty=k2*a1.x+m2; if(cmp(ty-miny)>=0&&cmp(ty-maxy)<=0) return 1; return 0; } return 0; } } else if(!get(a2,b2,k2,m2)) { double max1=max(a1.x,b1.x),min1=min(a1.x,b1.x); double maxy=max(a2.y,b2.y),miny=min(a2.y,b2.y); if(cmp(a2.x-min1)>=0&&cmp(a2.x-max1)<=0) { double ty=k1*a2.x+m1; if(cmp(ty-miny)>=0&&cmp(ty-maxy)<=0) return 1; return 0; } return 0; } else { double x,y; if(cmp(k1-k2)==0) { if(cmp(m1-m2)==0) //位于同一直线 { double max1=max(a1.y,b1.y),max2=max(a2.y,b2.y); double min1=min(a1.y,b1.y),min2=min(a2.y,b2.y); if(cmp(max2-min1)>=0&&cmp(max1-max2)>=0) return 1; if(cmp(max1-min2)>=0&&cmp(max2-max1)>=0) return 1; return 0; } else return 0; //平行 } x=(m2-m1)/(k1-k2); y=k1*x+m1; double max1=max(a1.y,b1.y),max2=max(a2.y,b2.y); double min1=min(a1.y,b1.y),min2=min(a2.y,b2.y); if(cmp(y-min1)>=0&&cmp(max1-y)>=0&&cmp(y-min2)>=0&&cmp(max2-y)>=0) return 1; return 0; } } int main() { int t; P a1,b1,a2,b2; cin>>t; while(t--) { cin>>a1.x>>a1.y>>b1.x>>b1.y>>a2.x>>a2.y>>b2.x>>b2.y; if(judge(a1,b1,a2,b2)) puts("Yes"); else puts("No"); } return 0; }
更加方便的解法是利用向量。
http://www.cnblogs.com/zhangchaoyang/articles/2668562.html