Advertisement
Guest User

Untitled

a guest
Mar 31st, 2020
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.06 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. struct rect {
  5. int xlo, xhi, ylo, yhi;
  6. };
  7.  
  8. int signum(int a) { return (a > 0) - (a < 0); }
  9.  
  10. int main() {
  11. ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  12. int X, Y; cin >> X >> Y;
  13. vector<rect> windows;
  14.  
  15. string OP;
  16. int commandNum = 1;
  17. for (; cin >> OP; commandNum++) {
  18. auto err = [&]() -> ostream& {
  19. return cout << "Command " << commandNum << ": " << OP << " - ";
  20. };
  21.  
  22. auto doesNotFit = [&]() {
  23. err() << "window does not fit" << '\n';
  24. };
  25. auto noWindow = [&]() {
  26. err() << "no window at given position" << '\n';
  27. };
  28. auto moved = [&](int actual, int orig) {
  29. assert(0 <= actual && actual <= orig);
  30. if (actual < orig) {
  31. err() << "moved " << actual << " instead of " << orig << '\n';
  32. }
  33. };
  34.  
  35. auto findWindow = [&](int x, int y) -> int {
  36. for (int i = 0; i < int(windows.size()); i++) {
  37. rect r = windows[i];
  38. if (r.xlo <= x && x < r.xhi && r.ylo <= y && y < r.yhi) {
  39. return i;
  40. }
  41. }
  42. return -1;
  43. };
  44.  
  45. auto intersects = [&](rect a, rect r) -> bool {
  46. return max(a.xlo, r.xlo) < min(a.xhi, r.xhi) && max(a.ylo, r.ylo) < min(a.yhi, r.yhi);
  47. };
  48.  
  49. auto checkFits = [&](rect a, int x) -> bool {
  50. if (a.xlo < 0 || a.ylo < 0 || a.xhi > X || a.yhi > Y) {
  51. return false;
  52. }
  53. for (int i = 0; i < int(windows.size()); i++) {
  54. if (i == x) continue;
  55. if (intersects(a, windows[i])) {
  56. return false;
  57. }
  58. }
  59. return true;
  60. };
  61.  
  62. auto go = [&]() {
  63. if (OP == "OPEN") {
  64. int xlo, ylo, xhi, yhi; cin >> xlo >> ylo >> xhi >> yhi;
  65. xhi += xlo, yhi += ylo;
  66. rect n{xlo, xhi, ylo, yhi};
  67. if (!checkFits(n, -1)) {
  68. doesNotFit();
  69. return;
  70. }
  71. windows.push_back(n);
  72. } else if (OP == "CLOSE") {
  73. int x, y; cin >> x >> y;
  74. int i = findWindow(x, y);
  75. if (i == -1) {
  76. noWindow();
  77. return;
  78. }
  79.  
  80. windows.erase(windows.begin() + i);
  81. } else if (OP == "RESIZE") {
  82. int x, y; cin >> x >> y;
  83. int w, h; cin >> w >> h;
  84. int i = findWindow(x, y);
  85. if (i == -1) {
  86. noWindow();
  87. return;
  88. }
  89.  
  90. rect n = windows[i];
  91. n.xhi = n.xlo + w;
  92. n.yhi = n.ylo + h;
  93. if (!checkFits(n, i)) {
  94. doesNotFit();
  95. return;
  96. }
  97.  
  98. windows[i] = n;
  99. } else if (OP == "MOVE") {
  100. int x, y; cin >> x >> y;
  101. int dx, dy; cin >> dx >> dy;
  102. int i = findWindow(x, y);
  103. if (i == -1) {
  104. noWindow();
  105. return;
  106. }
  107.  
  108. const int INF = X+Y+1;
  109. int orig = abs(dx) + abs(dy);
  110. int actual = 0;
  111. auto getAMove = [&](rect a, rect b) -> int {
  112. if (dx < 0) {
  113. if (max(a.ylo, b.ylo) < min(a.yhi, b.yhi) && b.xhi <= a.xlo) {
  114. return a.xlo - b.xhi;
  115. }
  116. } else if (dx > 0) {
  117. if (max(a.ylo, b.ylo) < min(a.yhi, b.yhi) && a.xhi <= b.xlo) {
  118. return b.xlo - a.xhi;
  119. }
  120. } else if (dy < 0) {
  121. if (max(a.xlo, b.xlo) < min(a.xhi, b.xhi) && b.yhi <= a.ylo) {
  122. return a.ylo - b.yhi;
  123. }
  124. } else if (dy > 0) {
  125. if (max(a.xlo, b.xlo) < min(a.xhi, b.xhi) && a.yhi <= b.ylo) {
  126. return b.ylo - a.yhi;
  127. }
  128. } else assert(false);
  129. return INF;
  130. };
  131.  
  132. vector<bool> toMove(windows.size());
  133. toMove[i] = true;
  134. while (orig > actual) {
  135. int legalAmt = orig - actual;
  136. for (int a = 0; a < int(windows.size()); a++) {
  137. if (!toMove[a]) continue;
  138. legalAmt = min(legalAmt, getAMove(windows[a], rect{0, X, -1, 0}));
  139. legalAmt = min(legalAmt, getAMove(windows[a], rect{0, X, Y, Y+1}));
  140. legalAmt = min(legalAmt, getAMove(windows[a], rect{-1, 0, 0, Y}));
  141. legalAmt = min(legalAmt, getAMove(windows[a], rect{X, X+1, 0, Y}));
  142. }
  143.  
  144. if (legalAmt == 0) break; // hit a wall
  145.  
  146. //cerr << "legalAmt " << legalAmt << '\n';
  147.  
  148. for (int a = 0; a < int(windows.size()); a++) {
  149. if (!toMove[a]) continue;
  150. for (int b = 0; b < int(windows.size()); b++) {
  151. if (toMove[b]) continue;
  152. int d = getAMove(windows[a], windows[b]);
  153. legalAmt = min(legalAmt, d);
  154. }
  155. }
  156. actual += legalAmt;
  157. for (int a = 0; a < int(windows.size()); a++) {
  158. if (!toMove[a]) continue;
  159. windows[a].xlo += signum(dx) * legalAmt;
  160. windows[a].xhi += signum(dx) * legalAmt;
  161. windows[a].ylo += signum(dy) * legalAmt;
  162. windows[a].yhi += signum(dy) * legalAmt;
  163. }
  164. for (int a = 0; a < int(windows.size()); a++) {
  165. if (!toMove[a]) continue;
  166. for (int b = 0; b < int(windows.size()); b++) {
  167. if (toMove[b]) continue;
  168. int d = getAMove(windows[a], windows[b]);
  169. if (!d) {
  170. toMove[b] = true;
  171. }
  172. }
  173. }
  174. }
  175. moved(actual, orig);
  176. } else assert(false);
  177. };
  178.  
  179. go();
  180.  
  181. //cerr << "Finished command " << commandNum << '\n';
  182. //for (auto r : windows) { cerr << r.xlo << ' ' << r.ylo << ' ' << r.xhi << ' ' << r.yhi << '\n'; }
  183. }
  184.  
  185. cout << windows.size() << " window(s):" << '\n';
  186. for (auto r : windows) {
  187. cout << r.xlo << ' ' << r.ylo << ' ' << r.xhi - r.xlo << ' ' << r.yhi - r.ylo << '\n';
  188. }
  189.  
  190. return 0;
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement