题解:P14153 [ICPC 2022 Nanjing R] 停停,昨日请不要再重现
liujianchong · · 题解
题解:P14153 [ICPC 2022 Nanjing R] 停停,昨日请不要再重现
Problem
给你一个
Solution
首先,容易想到的是,这个移动路径是有范围的,于是考虑统计
然后,由于每个袋鼠的移动路径都是全等的,所以可以取一个点(此处取左上角
那么再利用我们惊人的注意力就会发现,每一个袋鼠与左上角那个袋鼠的相对位置不改变,于是就会发现,对于代表路径上的每个点,以之为左上角的一个矩形内的格子都是可以抓住袋鼠的。而这个矩形的大小就是前面所说较小矩形的大小。
对于范围内的部分,我们需要记录一下这个位置能抓住一只袋鼠,于是我们就得到了每个范围内的点能抓住几只袋鼠,如果这个数量等于
Implementation
先求出小矩形的位置,然后求出其中左上角袋鼠的路径上的所有点,然后利用二维差分,对以这些点为左上角,小矩形大小为大小的矩形内的点的标记全部
If you TLE
本人已经连续被 memset 坑了两回了(这是第二回),所以,当你 TLE 的时候,删删没用的 memset 吧。
Code
AC Record
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 0x3f3f3f3f;
const int N = 1005;
bool vis[N][N];
int chafen[N][N], cfqzh[N][N];
pair<int, int> lujing[N * N];
int ljcnt;
int t, n, m, k;
string s;
signed main() {
ios :: sync_with_stdio(false);
cin >> t;
while (t--) {
memset(vis, 0, sizeof(vis));
memset(chafen, 0, sizeof(chafen));
memset(cfqzh, 0, sizeof(cfqzh));
ljcnt = 0;
cin >> n >> m >> k >> s;
int len = s.length();
int minx = inf, maxx = -inf, miny = inf, maxy = -inf, dx = 0, dy = 0;
for (int i = 0; i < len; i++) {
switch (s[i]) {
case 'U': {
dy--;
break;
}
case 'D': {
dy++;
break;
}
case 'L': {
dx--;
break;
}
case 'R': {
dx++;
break;
}
default:
break;
}
minx = min(minx, dx);
maxx = max(maxx, dx);
miny = min(miny, dy);
maxy = max(maxy, dy);
}
int u = max(1ll, 1ll - miny);
int d = min(n, n - maxy);
int l = max(1ll, 1ll - minx);
int r = min(m, m - maxx);
if (l > r || u > d || (r - l + 1) * (d - u + 1) <= 0) {
if (k)
cout << "0\n";
else
cout << n * m << "\n";
continue;
}
int x = u, y = l;
vis[x][y] = 1;
lujing[++ljcnt] = make_pair(x, y);
for (int i = 0; i < len; i++) {
switch (s[i]) {
case 'U': {
x--;
break;
}
case 'D': {
x++;
break;
}
case 'L': {
y--;
break;
}
case 'R': {
y++;
break;
}
default:
break;
}
if (!vis[x][y]) {
vis[x][y] = true;
lujing[++ljcnt] = make_pair(x, y);
}
}
for (int i = 1; i <= ljcnt; i++) {
x = lujing[i].first;
y = lujing[i].second;
int ex = x + d - u;
int ey = y + r - l;
chafen[x][y]++;
chafen[ex + 1][y]--;
chafen[x][ey + 1]--;
chafen[ex + 1][ey + 1]++;
}
int cnt = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cfqzh[i][j] = cfqzh[i - 1][j] + cfqzh[i][j - 1] - cfqzh[i - 1][j - 1] + chafen[i][j];
if ((r - l + 1) * (d - u + 1) - cfqzh[i][j] == k)
cnt++;
}
cout << cnt << "\n";
}
return 0;
}