Problem address: http://poj.org/problem? Id = 2653
[Preface]
Try to determine the intersection of line segments.
Geometric things have never dared to touch.
A battle in discuss.
Then write and write, and then it will be an AC.
[Idea]
How to determine the intersection of line segments?
Use the two ends of the two line segments to multiply the two ends of the other line segment. If both ends are less than zero, the two ends of the same line segment will intersection.
Enumerate each edge from the bottom up. If the current edge and the previous edge intersect, the previous edge cannot be the top stick.
N = 100000. Generally, algorithms with N2 complexity will time out.
However, since this question already shows that the top sticks cannot exceed M = 1000 at most.
Therefore, the complexity of nm is acceptable.
I used two arrays to simulate the linked list and implemented O (nm ).
By the way, you can refer to an address to explain various judgments, although I did not copy them from it.
Http://wenku.baidu.com/view/ae559264783e0912a2162a79.html
[Code]
# Include <iostream> using namespace STD; const int maxn = 100000; struct point {Double X; Double Y ;}; struct seg {point begin; point end ;} s [maxn + 5]; int CT; int next [maxn + 5]; int pre [maxn + 5]; inline double cross (point a, point B, point T) // calculate the cross product {return (. x-t.x) * (B. y-t.y)-(B. x-t.x) * (. y-t.y);} inline bool segcross (seg a, seg B) // judge the intersection {double d1 = cross (. begin,. end, B. begin); double D2 = cross (. begin,. end, B. end); double D3 = cross (B. begin, B. end,. begin); double D4 = cross (B. begin, B. end,. end); If (D1 * D2 <0 & D3 * D4 <0) return true; else return false;} int main () {int N; int I, J; while (scanf ("% d", & N )! = EOF) {If (n = 0) break; Ct = 0; for (I = 1; I <= N; I ++) {scanf ("% lf", & S [I]. begin. x, & S [I]. begin. y, & S [I]. end. x, & S [I]. end. y); next [I] = I + 1; Pre [I] = I-1;} next [0] = 1; next [N] =-1; Ct = N; for (I = 1; I <= N; I ++) {for (j = next [0]; j <I; j = next [J]) // compare with the preceding edge. Note that the starting point of J is next [0] To avoid deleting the first vertex. The storage location starts from 0 and the initial value of next [0] is 1. {If (segcross (s [I], s [J]) // If the intersection exists, remove the index {CT --; next [pre [J] = next [J]; Pre [next [J] = pre [J] ;}} printf ("top sticks :"); for (I = 0, j = next [0]; I <CT; I ++, j = next [J]) {if (I = 0) printf ("% d", J); else printf (", % d", J);} printf (". \ n ") ;}return 0 ;}