https://codeforces.com/gym/104128/problem/A
题意
思路
二维差分+经典模型
考虑如果没有洞那么经历操作之后会剩下什么样子的袋鼠。发现上下左右移动可以看成是边界在移动,边界一直保持一个原初的矩形形状,而且上下移动和左右移动没有任何关系。一旦边界移动到了一个位置,这个位置前面的袋鼠都会消失。
所以记录u,d,l,r,表示在移动时所产生的最小矩阵的上下左右边界,这样剩下的袋鼠数量就是有(d-u+1)*(r-l+1)个。
加入有洞的情况,发现洞产生的路径都可以通过平移获得,那么就只维护一条路径,就是从(0,0)点开始的路径,那么所有的点(i,j)的路径就是(0,0)点开始的路径上的点加(i,j)。 那么我们要维护有洞会让袋鼠消失多少,只有在u<=x<=d,l<=y<=r的才是有效被消失的袋鼠,那么就维护mp[i][j]表示从(i,j)点开始会让多少只袋鼠消失,发现对于点(x,y),只会对一个矩形内的数加1,左上角为(u-x,l-y),右下角为(d-x,r-y)的矩形,变成二维差分维护,那么在二维差分中给一个点加1等于给它往右往下的全部点加1.
注意:要去除经过的重复的点,重复点不能重复计算答案,因为他们去除的是同一片袋鼠。
Code:
#include <bits/stdc++.h>constexpr int N = 1e3 + 10;
constexpr int mod = 998244353;
constexpr int Inf = 0x3f3f3f3f;std::string s;int n, m, k;
int f[N][N];
int vis[N][N];void add(int x1, int y1, int x2, int y2) {f[x1][y1] ++;f[x2 + 1][y1] --;f[x1][y2 + 1] --;f[x2 + 1][y2 + 1] ++;
}
void solve() {std::cin >> n >> m >> k;for (int i = 0; i <= n + 5; i ++) {for (int j = 0; j <= m + 5; j ++) {vis[i][j] = f[i][j] = 0;}}std::cin >> s;int sz = s.size();s = " " + s;int u = 1, d = n, l = 1, r = m;int U = 1, D = n, L = 1, R = m;for (int i = 1; i <= sz; i ++) {if (s[i] == 'U') {u ++;d ++;}else if (s[i] == 'D') {u --;d --;}else if (s[i] == 'L') {l ++;r ++;}else {l --;r --;}U = std::max(U, u);D = std::min(D, d);L = std::max(L, l);R = std::min(R, r);}if (L > R || U > D) {if (k) {std::cout << 0 << "\n";}else {std::cout << n * m << "\n";}return;}int del = (R - L + 1) * (D - U + 1) - k;if (del < 0) {std::cout << 0 << "\n";return;}add(U, L, D, R);vis[L][U] = 1;for (int i = 1; i <= sz; i ++) {if (s[i] == 'L') {L --;R --;}else if (s[i] == 'R') {L ++;R ++;}else if (s[i] == 'U') {U --;D --;}else {U ++;D ++;}if (vis[L][U]) continue;vis[L][U] = 1;add(U, L, D, R);}for (int i = 1; i <= n; i ++) {for (int j = 1; j <= m; j ++) {f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];}}int ans = 0;for (int i = 1; i <= n; i ++) {for (int j = 1; j <= m; j ++) {if (f[i][j] == del) ans ++;}}std::cout << ans << "\n";
}
signed main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int t = 1;std::cin >> t;while (t--) {solve();}return 0;
}