HDU 1086 You can Solve a Geometry Problem too
分析:判断两直线是否相交:分两步:①:快速排斥实验设以线段P1P2为对角线的矩形为R,以线段Q1Q2为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。②:跨立实验如果两直线相交,则两直线必然相互跨立对方。若P1P2跨立Q1Q2,则矢量(P1-Q1)和(P2-Q1)位于矢量(Q2-Q1)的两侧,即(P1-Q1)X(Q2-Q1)*(P2-Q1)X(Q2-Q1)<0. 上式可改写为(P1-Q1)X(Q2-Q1)*(Q2-Q1)X(P2-Q1)>0. 当(P1-Q1)X(Q2-Q1)=0 时,说明(P1-Q1)和(Q2-Q1)共线,但因为已经通过快速排斥实验,所以P1一定在线段Q1Q2上,同理,(Q2-Q1)X(P2-Q1)=0 说明P2一定在直线Q1Q2上。所以判断P1P2跨立Q1Q2的依据是:(P1 - Q1) X (Q2 - Q1) * (Q2 - Q1) X (P2 -Q1)>=0
#include <cstdio> struct node{double x0,y0,x1,y1;}q[101]; int p(struct node a,struct node b){ double k1=(a.x0-b.x0)*(b.y1-b.y0)-(a.y0-b.y0)*(b.x1-b.x0); double k2=(b.x1-b.x0)*(a.y1-b.y0)-(b.y1-b.y0)*(a.x1-b.x0); if(k1*k2>=0)return 1; return 0; } int main(){ int t,tot=0,i,j; while(scanf("%d",&t),t){ for(i=0;i<t;i++)scanf("%lf%lf%lf%lf",&q[i].x0,&q[i].y0,&q[i].x1,&q[i].y1); for(i=0;i<t-1;i++) for(j=i+1;j<t;j++)tot+=(p(q[i],q[j])&&p(q[j],q[i])); printf("%d\n",tot); tot=0; } return 0; }
愿你出走半生,归来仍是少年