题目链接:http://poj.org/problem?id=2653
题解:线段相交判断 叉积基本运用
#include<cstdio> #include<cstring> #include<cmath> #define N 110000 bool ans[N]; //定义点 struct Point { double x, y; Point(double x = 0, double y = 0) : x(x), y(y) {} }; struct segment { Point a, b; }seg[N]; typedef Point Vector; //Vector 为 Point的别名 //向量+向量=向量 点+向量=点 Vector operator + (Vector A, Vector B) {return Vector(A.x+B.x, A.y+B.y);} //点-点=向量 Vector operator - (Point A, Point B) {return Vector(A.x-B.x, A.y-B.y);} //向量*数=向量 Vector operator * (Vector A, double p) {return Vector(A.x*p, A.y*p);} //向量/数=向量 Vector operator / (Vector A, double p) {return Vector(A.x/p, A.y/p);} bool operator < (const Point & a, const Point & b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } const double eps = 1e-10; int dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } //点积:两者长度乘积再乘上夹角余弦 XaXb + YaYb double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; } double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; } //线段相交判定(原理:大白书258) //每条线段的两个端点都在另一条线段的两侧 bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)//a,b线段 { double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1), c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1); return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4) < 0; } int main () { int n; while(scanf("%d", &n), n) { memset(ans, 0, sizeof(ans)); for(int i = 1; i <= n ;i++) scanf("%lf %lf %lf %lf", &seg[i].a.x, &seg[i].a.y, &seg[i].b.x, &seg[i].b.y); for(int i = 1; i <= n; i++) for(int j = i+1; j <= n; j++) { if(SegmentProperIntersection(seg[i].a, seg[i].b, seg[j].a, seg[j].b)) { ans[i] = 1; break; } } int flag = 0; printf("Top sticks:"); for(int i = 1; i <= n; i++) if(ans[i] == 0) { if(flag == 0) flag = 1; else printf(","); printf(" %d", i); } printf(".\n"); } return 0; }