给你 n 条线段,计算这 n 条线段总共的交点数目。
几何线段相交的裸题。
快速排斥实验 + 跨立实验,N^2 两两判断就可以。
关于上述判定线段相交的方法可以去百度资料,在此不再赘述。
#include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; #define maxn 200 + 100 struct Point { double x, y; Point (double xx = 0, double yy = 0) : x(xx), y(yy) {} Point operator - (const Point& a) { return Point(x-a.x, y-a.y); } }; Point a1[maxn], a2[maxn]; bool quick_exclude(Point a1, Point a2, Point b1, Point b2)//快速排斥实验 { if (max(a1.x, a2.x) < min(b1.x, b2.x)) return false; if (max(b1.x, b2.x) < min(a1.x, a2.x)) return false; if (max(a1.y, a2.y) < min(b1.y, b2.y)) return false; if (max(b1.y, b2.y) < min(a1.y, a2.y)) return false; return true; } double cross(Point a, Point b) //返回两个共面向量叉乘的z值 { return a.x * b.y - a.y * b.x; } bool walk_across(Point a1, Point a2, Point b1, Point b2)//跨立实验 { if (cross(a1-b1, b2-b1) * cross(a2-b1, b2-b1) > 0) return false; if (cross(b1-a1, a2-a1) * cross(b2-a1, a2-a1) > 0) return false; return true; } int main() { int n; while(~scanf("%d", &n) && n) { for (int i = 1; i <= n; i++) scanf("%lf%lf%lf%lf", &a1[i].x, &a1[i].y, &a2[i].x, &a2[i].y); int ans = 0; for (int i = 1; i <= n; i++) for (int j = i+1; j <= n; j++) { if (quick_exclude(a1[i], a2[i], a1[j], a2[j]) && walk_across(a1[i], a2[i], a1[j], a2[j])) ans++; } printf("%d\n", ans); } }