Advertisement
Guest User

Untitled

a guest
Mar 31st, 2020
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.91 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std; inline void fileio(const char* in, const char* out) { freopen(in, "r", stdin); freopen(out, "w", stdout); }
  3. #define TD typedef
  4. #define forx(i,n) for(int i = 0; i < (n); ++i)
  5. #define forxr(i,n) for(int i = (n)-1; i >= 0; --i)
  6. TD long long ll; TD long double ld; TD pair<int,int> pii; TD pair<ll,ll> pll; TD vector<int> VI; TD vector<bool> VB; TD vector<ll> VL;
  7. const char nl = '\n'; const int INF = 0x3f3f3f3f; const ll LINF = 0x3f3f3f3f3f3f3f3fll; const ld EPS = 1e-9, PI = acos(-1);
  8. #define ff first
  9. #define ss second
  10. #define all(c) c.begin(),c.end()
  11.  
  12. int x_max, y_max;
  13. struct Window {
  14. int x, y, w, h;
  15. Window(int a, int b, int c, int d) : x(a), y(b), w(c), h(d) {}
  16. bool isect(const Window& o) const {
  17. return
  18. (x < o.x+o.w && x+w > o.x) &&
  19. (y < o.y+o.h && y+h > o.y);
  20. }
  21. bool contains(int a, int b) const {
  22. return
  23. (x <= a && a < x+w) &&
  24. (y <= b && b < y+h);
  25. }
  26. bool oob() const {
  27. return x < 0 || y < 0 || x+w > x_max || y+h > y_max;
  28. }
  29. void flip() {
  30. swap(x,y);
  31. swap(w,h);
  32. }
  33. void neg() {
  34. x = -x - w;
  35. }
  36. };
  37.  
  38. int cur = 1;
  39. vector<Window> windows;
  40.  
  41. int _get(int x, int y) {
  42. for (int i = 0; i < windows.size(); ++i) {
  43. if (windows[i].contains(x,y)) return i;
  44. }
  45. return -1;
  46. }
  47.  
  48. void _open() {
  49. int x, y, w, h;
  50. cin >> x >> y >> w >> h;
  51. Window nwin(x,y,w,h);
  52. if (nwin.oob()) {
  53. printf("Command %d: OPEN - window does not fit\n", cur);
  54. return;
  55. }
  56. for (auto& win : windows) {
  57. if (nwin.isect(win)) {
  58. printf("Command %d: OPEN - window does not fit\n", cur);
  59. return;
  60. }
  61. }
  62. windows.push_back(nwin);
  63. }
  64.  
  65. void _resize() {
  66. int x, y, w, h;
  67. cin >> x >> y >> w >> h;
  68. int idx = _get(x,y);
  69. if (idx == -1) {
  70. printf("Command %d: RESIZE - no window at given position\n", cur);
  71. return;
  72. }
  73. Window nwin = windows[idx];
  74. nwin.w = w;
  75. nwin.h = h;
  76. if (nwin.oob()) {
  77. printf("Command %d: RESIZE - window does not fit\n", cur);
  78. return;
  79. }
  80. for (int i = 0; i < windows.size(); ++i) {
  81. if (i == idx) continue;
  82. if (nwin.isect(windows[i])) {
  83. printf("Command %d: RESIZE - window does not fit\n", cur);
  84. return;
  85. }
  86. }
  87. windows[idx] = nwin;
  88. }
  89.  
  90. void _move() {
  91. int x, y, dx, dy;
  92. cin >> x >> y >> dx >> dy;
  93. int idx = _get(x,y);
  94. if (idx == -1) {
  95. printf("Command %d: MOVE - no window at given position\n", cur);
  96. return;
  97. }
  98. if (dy) {
  99. for (auto& w : windows) w.flip();
  100. swap(x_max, y_max);
  101. dx = dy;
  102. }
  103. int pre = 0;
  104. if (dx < 0) {
  105. swap(x_max, pre);
  106. for (auto& w : windows) w.neg();
  107. dx = -dx;
  108. }
  109. //handle dx
  110. const int requested = dx;
  111. int moved = 0;
  112. set<int> moving = {idx};
  113. while (dx) {
  114. int next_hit = -1;
  115. int dist = INF;
  116. //hitting the wall
  117. for (int i : moving) {
  118. assert(windows[i].x + windows[i].w <= x_max);
  119. dist = min(dist, x_max - windows[i].x - windows[i].w);
  120. }
  121. assert(dist >= 0);
  122. //hitting a thing
  123. for (int i = 0; i < windows.size(); ++i) {
  124. if (moving.count(i)) continue;
  125. const Window& hit = windows[i];
  126. for (int j : moving) {
  127. const Window& mov = windows[j];
  128. if (hit.y < mov.y+mov.h && hit.y+hit.h > mov.y && mov.x+mov.w <= hit.x) {
  129. int d = hit.x - mov.x - mov.w;
  130. assert(d >= 0);
  131. if (d < dist) {
  132. next_hit = i;
  133. dist = d;
  134. }
  135. }
  136. }
  137. }
  138. int mv = min(dx, dist);
  139. assert(mv >= 0);
  140. moved += mv;
  141. for (int i : moving) {
  142. windows[i].x += mv;
  143. }
  144. dx -= mv;
  145. if (mv < dx) {
  146. if (next_hit == -1) {
  147. break;
  148. }
  149. assert(moving.count(next_hit)==0);
  150. moving.insert(next_hit);
  151. }
  152. }
  153. assert(moved <= requested);
  154. if (moved != requested) {
  155. printf("Command %d: MOVE - moved %d instead of %d\n", cur, moved, requested);
  156. }
  157. if (x_max == 0) {
  158. swap(x_max, pre);
  159. for (auto& w : windows) w.neg();
  160. }
  161. if (dy) {
  162. for (auto& w : windows) w.flip();
  163. swap(x_max, y_max);
  164. }
  165. }
  166.  
  167. void _close() {
  168. int x, y;
  169. cin >> x >> y;
  170. int idx = _get(x,y);
  171. if (idx == -1) {
  172. printf("Command %d: CLOSE - no window at given position\n", cur);
  173. return;
  174. }
  175. windows.erase(windows.begin()+idx);
  176. }
  177.  
  178. void _report() {
  179. printf("%d window(s):\n", (int)windows.size());
  180. for (auto w : windows) {
  181. printf("%d %d %d %d\n", w.x, w.y, w.w, w.h);
  182. }
  183. }
  184.  
  185. map<string,function<void(void)>> cmds = {
  186. {"OPEN", _open},
  187. {"RESIZE", _resize},
  188. {"MOVE", _move},
  189. {"CLOSE", _close}
  190. };
  191.  
  192. int main() { // Emily <3
  193. atexit([](){ cerr << "Time: " << (ld)clock() / CLOCKS_PER_SEC << nl; });
  194. ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  195. cout << fixed << setprecision(12);
  196. cin >> x_max >> y_max;
  197. string op;
  198. while(cin >> op) {
  199. cmds[op]();
  200. cur++;
  201. }
  202. _report();
  203.  
  204. return 0;
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement