Advertisement
Tooster

Shamos-Hoye

Jan 6th, 2016
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.90 KB | None | 0 0
  1. /*
  2. Working shamos-hoey algorithm in c++ - finds if any two line segments in set of segments intersects
  3. input:
  4. t - test cases,
  5. in each test case n - number of lines
  6. in n lines:
  7. start, end, a, b:
  8. start - x-cord of left endpoint
  9. end - xcord of right endpoint
  10. a, b are factors of line equation
  11. y = a*x + b
  12.  
  13. prints TAK if intersection exists, NIE if not
  14. */
  15. #include <cstdio>
  16. #include <set>
  17. #include <algorithm>
  18. #include <vector>
  19. #define ll long long
  20. using namespace std;
  21.  
  22. ll globalX;
  23.  
  24. struct point {
  25. ll x;
  26. ll y;
  27. bool left; //czy lewy
  28. int n; //do której lini należy
  29. point() {}
  30. point(const ll &x, const ll &y, bool l, const int &i) {
  31. this->x = x; this->y = y; left = l; n = i;
  32. }
  33. bool operator <(const point &p) const {
  34. return this->x < p.x;
  35. return this->y < p.y;
  36. }
  37. };
  38.  
  39. struct segment {
  40. point A, B;
  41. ll a, b;
  42. segment() {}
  43. segment(const point &P, const point &K) {
  44. A = P; B = K;
  45. B.x - A.x == 0 ? a = 0 : a = (B.y - A.y) / (B.x - A.x);
  46. b = A.y - a*A.x;
  47. }
  48. bool operator <(const segment &s) const {
  49. return a*globalX + b < s.a*globalX + s.b;
  50. }
  51. };
  52.  
  53. ll product(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) {
  54. return (((x2 - x1)*(y3 - y1)) - ((x3 - x1)*(y2 - y1)));
  55. }
  56.  
  57. bool between(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) { //dla pokrywających się
  58. if (
  59. (min(x1, x2) <= x3) && (x3 <= max(x1, x2)) &&
  60. (min(y1, y2) <= y3) && (y3 <= max(y1, y2))
  61. ) return true;
  62. return false;
  63. }
  64.  
  65. bool crossover(const segment &a, const segment &b) {
  66. ll p1 = product(a.A.x, a.A.y, b.A.x, b.A.y, a.B.x, a.B.y);
  67. ll p2 = product(a.A.x, a.A.y, b.B.x, b.B.y, a.B.x, a.B.y);
  68. ll p3 = product(b.A.x, b.A.y, a.A.x, a.A.y, b.B.x, b.B.y);
  69. ll p4 = product(b.A.x, b.A.y, a.B.x, a.B.y, b.B.x, b.B.y);
  70.  
  71. if (((p1 > 0 && p2 < 0) || (p1 < 0 && p2 > 0))
  72. &&
  73. ((p3 < 0 && p4 > 0) || (p3 > 0 && p4 < 0))) return true;
  74. else if (p1 == 0 && between(a.A.x, a.A.y, a.B.x, a.B.y, b.A.x, b.A.y)) return true;
  75. else if (p2 == 0 && between(a.A.x, a.A.y, a.B.x, a.B.y, b.B.x, b.B.y)) return true;
  76. else if (p3 == 0 && between(b.A.x, b.A.y, b.B.x, b.B.y, a.A.x, a.A.y)) return true;
  77. else if (p4 == 0 && between(b.A.x, b.A.y, b.B.x, b.B.y, a.B.x, a.B.y)) return true;
  78. else return false;
  79. }
  80.  
  81. bool f() {
  82. int n;
  83. scanf("%d", &n);
  84. vector<segment> S;
  85. S.resize(n);
  86. vector<point> points;
  87. points.resize(2 * n);
  88.  
  89. ll start, end;
  90. ll a, b;
  91. for (int i = 0; i < n; i++) {
  92. scanf("%lld %lld %lld %lld", &start, &end, &a, &b);
  93. points[2 * i] = point(start, start*a + b, true, i);
  94. points[2 * i + 1] = point(end, end*a + b, false, i);
  95. S[i] = segment(points[2 * i], points[2 * i + 1]);
  96. }
  97.  
  98. sort(points.begin(), points.end());
  99. multiset<segment> BST;
  100.  
  101. for (int i = 0; i < 2 * n; i++) {
  102. globalX = points[i].x;
  103. if (points[i].left) {
  104. multiset<segment>::iterator it = BST.insert(segment(S[points[i].n].A, S[points[i].n].B));
  105. multiset<segment>::iterator above;
  106. multiset<segment>::iterator below;
  107. if (it != BST.begin()) {
  108. below = (--it)++;
  109. if (crossover(*it, *below)) return true;
  110. }
  111. if (++it != BST.end()) {
  112. above = it--;
  113. if (crossover(*it, *above)) return true;
  114. }
  115. }
  116. else {
  117. segment a = segment(S[points[i].n].A, S[points[i].n].B);
  118. multiset<segment>::iterator it = BST.find(a);
  119. if (it != BST.begin() && ++it != BST.end()) {
  120. multiset<segment>::iterator above = it;
  121. multiset<segment>::iterator below = --(--it);
  122. if (crossover(*above, *below)) return true;
  123. BST.erase(*(++it));
  124. }
  125. }
  126. }
  127. return false;
  128. }
  129.  
  130. int main() {
  131. int z;
  132. scanf("%d", &z);
  133. while (z--) {
  134. if (f()) printf("TAK\n");
  135. else printf("NIE\n");
  136. }
  137. return 0;
  138. }
  139. /*
  140. 2
  141. 3
  142. 0 5 1 0
  143. 5 10 -1 5
  144. 10 15 0 0
  145.  
  146. 4
  147. 0 5 0 0
  148. 0 5 0 1
  149. 0 3 -1 3
  150. 0 3 1 -1
  151.  
  152. > NIE
  153. > TAK
  154. === OK
  155. 1
  156. 3
  157. 0 6 -1 5
  158. 3 5 -1 7
  159. 4 5 -5 26
  160.  
  161. > TAK
  162. === OK
  163. 1
  164. 3
  165. 0 5 1 0
  166. 5 10 -1 10
  167. 10 15 0 0
  168.  
  169. > TAK
  170. === OK
  171. 1
  172. 5
  173. 0 10 1 0
  174. 1 10 1 1
  175. 2 10 1 2
  176. 3 10 1 3
  177. 4 10 1 5
  178.  
  179. > NIE
  180. == OK
  181. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement