题意:有些人没事儿喜欢往地上任棍子,后面扔的可能盖住前面扔的,显然最后扔的那根棍子一定没被压住,求所有没有被其它棍子压住的棍子。
题解:规范相交。用链表优化下。当然也可以用队列存储下标。
#include<cmath> #include<iostream> using namespace std; #define eps 1e-8 #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) struct Point { double x, y; }; struct Line { Point a, b; }; struct NODE { Line l; int id; NODE *next, *pre; } node[200000]; double xmult ( Point p1, Point p2, Point p0 ) { return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } int opposite_side ( Point p1, Point p2, Point l1, Point l2 ) { return xmult ( l1, p1, l2 ) * xmult ( l1, p2, l2 ) < -eps; } int intersect_ex ( Line u, Line v ) { if ( max(u.a.x, u.b.x) > min(v.a.x, v.b.x) && max(v.a.x, v.b.x) > min(u.a.x, u.b.x) && max(u.a.y, u.b.y) > min(v.a.y, v.b.y) && max(v.a.y, v.b.y) > min(u.a.y, u.b.y) && opposite_side ( u.a, u.b, v.a, v.b ) && opposite_side ( v.a, v.b, u.a, u.b ) ) return 1; return 0; } void insert ( NODE *& last, NODE *nod ) { nod->pre = last; nod->next = NULL; last->next = nod; last = nod; } void del ( NODE *nod ) { nod->next->pre = nod->pre; nod->pre->next = nod->next; } int main() { int n; while ( scanf("%d",&n) && n ) { NODE first, *last, *p, *tmp; first.next = NULL; last = NULL; for ( int i = 1; i <= n; i++ ) { scanf("%lf %lf %lf %lf", &node[i].l.a.x, &node[i].l.a.y, &node[i].l.b.x, &node[i].l.b.y ); node[i].id = i; if ( last == NULL ) { last = &node[i]; last->next = NULL; last->pre = &first; first.next = last; continue; } insert ( last, &node[i] ); p = last->pre; while ( p != &first ) { tmp = p->pre; if ( intersect_ex ( last->l, p->l ) ) del ( p ); p = tmp; } } printf("Top sticks: "); p = first.next; while ( p != NULL ) { printf("%d",p->id); if ( p->next == NULL ) printf(".\n"); else printf(", "); p = p->next; } } return 0; }