GYM 104128 A
A.Stop, Yesterday Please No More
首先,可以先不考虑洞,算出只存在边界影响的情况下剩下的袋鼠数量。
如果剩下袋鼠数量为零,那么可以直接判断当\(k>0\)时输出\(0\),当\(k=0\)时输出\(n*m\)。
如果袋鼠数量不为零,则可以先计算出剩下的袋鼠矩形中袋鼠的数量\(num\),和一开始所站位置的上边界\(x\)坐标,下边界\(x\)坐标,左边界\(y\)坐标,右边界\(y\)坐标。因为矩阵内的所有袋鼠所有的行走轨迹相同,所以每一个袋鼠行走路径中的每一个方格,都能找到其他袋鼠通过x和y偏移后的着地位置。所以只要维护一个二维的差分矩阵,表示出整个地图内每个位置有多少只不同的袋鼠经过,最后再用二维前缀和公式计算出原矩阵,并记录原矩阵中值为\(num-k\)的数量,输出即可。
代码
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PII;
const int N = 1e3 + 10;
int t;
int n, m, k;
string s;
bool v[N][N];
int c[N][N];
int a[N][N];
void add(int x1, int y1, int x2, int y2)
{
if(v[x1][y1])
return;
v[x1][y1] = 1;
c[x1][y1]++;
c[x2 + 1][y1]--;
c[x1][y2 + 1]--;
c[x2 + 1][y2 + 1]++;
}
signed main()
{
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> t;
while(t--)
{
cin >> n >> m >> k >> s;
int up = 0, down = 0, left = 0, right = 0;
int si = s.size();
int x = 0, y = 0;
memset(c, 0, sizeof(c));
memset(a, 0, sizeof(a));
memset(v, 0, sizeof(v));
for(int i = 0;i < si;i++)
{
if(s[i] == 'U')
{
x--;
up = min(up, x);
}
else if(s[i] == 'D')
{
x++;
down = max(down, x);
}
else if(s[i] == 'L')
{
y--;
left = min(left, y);
}
else
{
y++;
right = max(right, y);
}
}
int num = max(0, n + up - down) * max(0, m + left - right);
if(!num)
{
if(k > 0)
{
cout << "0" << endl;
}
else
{
cout << n * m << endl;
}
continue;
}
int U = -up, D = n - down - 1, L = -left, R = m - right - 1;
add(U + 1, L + 1, D + 1, R + 1);
for(int i = 0;i < si;i++)
{
if(s[i] == 'U')
{
U--;
D--;
add(U + 1, L + 1, D + 1, R + 1);
}
else if(s[i] == 'D')
{
U++;
D++;
add(U + 1, L + 1, D + 1, R + 1);
}
else if(s[i] == 'L')
{
L--;
R--;
add(U + 1, L + 1, D + 1, R + 1);
}
else
{
L++;
R++;
add(U + 1, L + 1, D + 1, R + 1);
}
}
int ans = 0;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + c[i][j];
if(a[i][j] == num - k)
{
ans++;
}
}
}
cout << ans << endl;
}
return 0;
}

浙公网安备 33010602011771号