标签:
传送门:You can Solve a Geometry Problem too
题意:给n条线段,判断相交的点数。
分析:判断线段相交模板题,快速排斥实验原理就是每条线段代表的向量和该线段的一个端点与 另一条线段的两个端点构成的两个向量求叉积,如果线段相交那么另一条线段两个端点必定在该线段的两边,则该线段代表的向量必定会顺时针转一遍逆时针转一遍,叉积必定会小于等于0,同样对另一条线段这样判断一次即可。
#include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #define N 1010 #define PI acos(-1.0) using namespace std; const double eps=1e-8; int sgn(double x) { if(fabs(x)<eps)return 0; if(x<0)return -1; return 1; } struct Point { double x,y; Point(){} Point(double _x,double _y):x(_x),y(_y){} Point operator -(const Point &a)const { return Point(x-a.x,y-a.y); } double operator *(const Point &a)const { return a.x*x+a.y*y; } double operator ^(const Point &a)const { return x*a.y-y*a.x; } }; struct Line { Point s,e; Line(){} Line(Point _s,Point _e):s(_s),e(_e){} }; bool segcrossseg(Line l1,Line l2) { return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&& max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&& max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&& max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&& sgn((l1.s-l1.e)^(l2.s-l1.e))*sgn((l1.s-l1.e)^(l2.e-l1.e))<=0&& sgn((l2.s-l2.e)^(l1.s-l2.e))*sgn((l2.s-l2.e)^(l1.e-l2.e))<=0; } Line L[110]; int main() { int n; while(scanf("%d",&n),n) { for(int i=1;i<=n;i++) { double a,b,c,d; scanf("%lf%lf%lf%lf",&a,&b,&c,&d); L[i]=Line(Point(a,b),Point(c,d)); } int ans=0; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(segcrossseg(L[i],L[j]))ans++; printf("%d\n",ans); } }
标签:
原文地址:http://www.cnblogs.com/lienus/p/4331151.html