hdu 1086(判断线段相交)

/* * 题目要求:求一组线段的总的交点数 * 判断两线段相交:1快速排斥,2跨立实验 */ #include <cstdio> #include <cstdlib> #include <iostream> using namespace std; const int N = 100; struct point {//点结构 double x; double y; }; struct segment {//线段结构 point s; point e; }seg[N]; double crossProd(point A, point B, point C) { return (B.x-A.x)*(C.y-A.y) - (B.y-A.y)*(C.x-A.x); } int segIntersect(segment seg1, segment seg2) {//判断线段是否相交 if (max(seg1.s.x, seg1.e.x) >= min(seg2.s.x, seg2.e.x) &&//快速排斥实验 max(seg2.s.x, seg2.e.x) >= min(seg1.s.x, seg1.e.x) && max(seg1.s.y, seg1.e.y) >= min(seg2.s.y, seg2.e.y) && max(seg2.s.y, seg2.e.y) >= min(seg1.s.y, seg1.e.y) && crossProd(seg2.s, seg2.e, seg1.s) * crossProd(seg2.s, seg1.e, seg2.e) >= 0 &&//跨立实验 crossProd(seg1.s, seg1.e, seg2.s) * crossProd(seg1.s, seg2.e, seg1.e) >= 0) return 1;//相交 return 0; } int solve(int n) { int c = 0; for (int i=0; i<n; ++i) { for (int j=i+1; j<n; ++j) c += segIntersect(seg[i], seg[j]); } return c; } int main() { int n; while (scanf("%d", &n), n) { for (int i=0; i<n; ++i) scanf ("%lf%lf%lf%lf", &seg[i].s.x, &seg[i].s.y, &seg[i].e.x, &seg[i].e.y); int c = solve(n); printf ("%d\n", c); } return 0; }