Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std; inline void fileio(const char* in, const char* out) { freopen(in, "r", stdin); freopen(out, "w", stdout); }
- #define TD typedef
- #define forx(i,n) for(int i = 0; i < (n); ++i)
- #define forxr(i,n) for(int i = (n)-1; i >= 0; --i)
- 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;
- const char nl = '\n'; const int INF = 0x3f3f3f3f; const ll LINF = 0x3f3f3f3f3f3f3f3fll; const ld EPS = 1e-9, PI = acos(-1);
- #define ff first
- #define ss second
- #define all(c) c.begin(),c.end()
- int x_max, y_max;
- struct Window {
- int x, y, w, h;
- Window(int a, int b, int c, int d) : x(a), y(b), w(c), h(d) {}
- bool isect(const Window& o) const {
- return
- (x < o.x+o.w && x+w > o.x) &&
- (y < o.y+o.h && y+h > o.y);
- }
- bool contains(int a, int b) const {
- return
- (x <= a && a < x+w) &&
- (y <= b && b < y+h);
- }
- bool oob() const {
- return x < 0 || y < 0 || x+w > x_max || y+h > y_max;
- }
- void flip() {
- swap(x,y);
- swap(w,h);
- }
- void neg() {
- x = -x - w;
- }
- };
- int cur = 1;
- vector<Window> windows;
- int _get(int x, int y) {
- for (int i = 0; i < windows.size(); ++i) {
- if (windows[i].contains(x,y)) return i;
- }
- return -1;
- }
- void _open() {
- int x, y, w, h;
- cin >> x >> y >> w >> h;
- Window nwin(x,y,w,h);
- if (nwin.oob()) {
- printf("Command %d: OPEN - window does not fit\n", cur);
- return;
- }
- for (auto& win : windows) {
- if (nwin.isect(win)) {
- printf("Command %d: OPEN - window does not fit\n", cur);
- return;
- }
- }
- windows.push_back(nwin);
- }
- void _resize() {
- int x, y, w, h;
- cin >> x >> y >> w >> h;
- int idx = _get(x,y);
- if (idx == -1) {
- printf("Command %d: RESIZE - no window at given position\n", cur);
- return;
- }
- Window nwin = windows[idx];
- nwin.w = w;
- nwin.h = h;
- if (nwin.oob()) {
- printf("Command %d: RESIZE - window does not fit\n", cur);
- return;
- }
- for (int i = 0; i < windows.size(); ++i) {
- if (i == idx) continue;
- if (nwin.isect(windows[i])) {
- printf("Command %d: RESIZE - window does not fit\n", cur);
- return;
- }
- }
- windows[idx] = nwin;
- }
- void _move() {
- int x, y, dx, dy;
- cin >> x >> y >> dx >> dy;
- int idx = _get(x,y);
- if (idx == -1) {
- printf("Command %d: MOVE - no window at given position\n", cur);
- return;
- }
- if (dy) {
- for (auto& w : windows) w.flip();
- swap(x_max, y_max);
- dx = dy;
- }
- int pre = 0;
- if (dx < 0) {
- swap(x_max, pre);
- for (auto& w : windows) w.neg();
- dx = -dx;
- }
- //handle dx
- const int requested = dx;
- int moved = 0;
- set<int> moving = {idx};
- while (dx) {
- int next_hit = -1;
- int dist = INF;
- //hitting the wall
- for (int i : moving) {
- assert(windows[i].x + windows[i].w <= x_max);
- dist = min(dist, x_max - windows[i].x - windows[i].w);
- }
- assert(dist >= 0);
- //hitting a thing
- for (int i = 0; i < windows.size(); ++i) {
- if (moving.count(i)) continue;
- const Window& hit = windows[i];
- for (int j : moving) {
- const Window& mov = windows[j];
- if (hit.y < mov.y+mov.h && hit.y+hit.h > mov.y && mov.x+mov.w <= hit.x) {
- int d = hit.x - mov.x - mov.w;
- assert(d >= 0);
- if (d < dist) {
- next_hit = i;
- dist = d;
- }
- }
- }
- }
- int mv = min(dx, dist);
- assert(mv >= 0);
- moved += mv;
- for (int i : moving) {
- windows[i].x += mv;
- }
- dx -= mv;
- if (mv < dx) {
- if (next_hit == -1) {
- break;
- }
- assert(moving.count(next_hit)==0);
- moving.insert(next_hit);
- }
- }
- assert(moved <= requested);
- if (moved != requested) {
- printf("Command %d: MOVE - moved %d instead of %d\n", cur, moved, requested);
- }
- if (x_max == 0) {
- swap(x_max, pre);
- for (auto& w : windows) w.neg();
- }
- if (dy) {
- for (auto& w : windows) w.flip();
- swap(x_max, y_max);
- }
- }
- void _close() {
- int x, y;
- cin >> x >> y;
- int idx = _get(x,y);
- if (idx == -1) {
- printf("Command %d: CLOSE - no window at given position\n", cur);
- return;
- }
- windows.erase(windows.begin()+idx);
- }
- void _report() {
- printf("%d window(s):\n", (int)windows.size());
- for (auto w : windows) {
- printf("%d %d %d %d\n", w.x, w.y, w.w, w.h);
- }
- }
- map<string,function<void(void)>> cmds = {
- {"OPEN", _open},
- {"RESIZE", _resize},
- {"MOVE", _move},
- {"CLOSE", _close}
- };
- int main() { // Emily <3
- atexit([](){ cerr << "Time: " << (ld)clock() / CLOCKS_PER_SEC << nl; });
- ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- cout << fixed << setprecision(12);
- cin >> x_max >> y_max;
- string op;
- while(cin >> op) {
- cmds[op]();
- cur++;
- }
- _report();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement