题解 CF555C 【Case of Chocolate】

吹雪吹雪吹

2019-03-30 09:38:04

Solution

观察样例,发现格子被吃之后会被分割成这样几种形状: ```cpp 1. 跟原来长得一样 # # # # # # # # # # # # # # # ----------- 2.1 比原来多出一块(前几行): # # # # # # # # # # # # # # # # # # # # # # # # # ----------- 2.2 比原来多出一块(前几列): # # # # # # # # # # # # # # # # # # ----------- 3. 比原来多出两块: # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ----------- 4. 某些矩形,肯定不会再被吃到 ``` 这样一来,一块区域就可以用四个量来表示:左右边界,向上和向左延伸的长度 用set维护即可: ```cpp #include <cstdio> #include <cstring> #include <algorithm> #include <set> using namespace std; int n, m, ans; class Squares { public: int l, r; int len_l, len_u; Squares() { l = r = 0; len_l = len_u = 0; } Squares(int _l, int _r, int _len_l, int _len_u) { l = _l, r = _r; len_l = _len_l, len_u = _len_u; } bool operator < (const Squares &b)const { return r < b.r; } } a, res, nxt; set<Squares> s; set<Squares>::iterator it; inline int read() { char ch = getchar(); int ret = 0, f = 1; while (ch > '9' || ch < '0') { if (ch == '-') f = -f; ch = getchar(); } while (ch >= '0' && ch <= '9') ret = ret * 10 + ch - '0', ch = getchar(); return ret * f; } int main() { // freopen("test.in", "r", stdin); // freopen("test.out", "w", stdout); n = read(), m = read(); res = Squares(1, n, 0, 0); s.insert(res); while (m--) { int x = read(), y = read(); char ch = getchar(); while (ch != 'U' && ch != 'L') ch = getchar(); a = Squares(x, x, 0, 0); it = s.lower_bound(a); if (it == s.end() || it->l > x || it->r < x) { printf("0\n"); continue; } res = *it; s.erase(it); if (ch == 'U') { ans = res.r - x + 1 + res.len_u; printf("%d\n", ans); if (x != res.l) { nxt = Squares(res.l, x - 1, res.len_l, ans); s.insert(nxt); } if (x != res.r) { nxt = Squares(x + 1, res.r, 0, res.len_u); s.insert(nxt); } } else { ans = x - res.l + 1 + res.len_l; printf("%d\n", ans); if (x != res.l) { nxt = Squares(res.l, x - 1, res.len_l, 0); s.insert(nxt); } if (x != res.r) { nxt = Squares(x + 1, res.r, ans, res.len_u); s.insert(nxt); } } } return 0; } ```