题目大意:
给一个(n imes m)的矩阵和一个(a imes b)的单位矩阵,然后在(n imes m)的矩阵中任取(a imes b)的子矩阵,使其每一位都减(1),问最后能否使原始矩阵元素全变为(0)。
思路:
利用二维差分快速实现对矩阵元素进行更新。
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1010;
int n, m, a, b, T, mp[N][N];
LL p[N][N];
void update(int x1, int y1, int x2, int y2, LL v)
{
p[x1][y1] += v;
p[x1][y2 + 1] -= v;
p[x2 + 1][y1] -= v;
p[x2 + 1][y2 + 1] += v;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> T;
while (T--)
{
cin >> n >> m >> a >> b;
bool ok = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> mp[i][j];
p[i][j] = 1ll * mp[i][j] - mp[i - 1][j] - mp[i][j - 1] + mp[i - 1][j - 1];
}
}
for (int i = 1; i <= n - a + 1 && ok; i++)
{ //模拟更新
for (int j = 1; j <= m - b + 1 && ok; j++)
{
int i1 = i + a - 1, j1 = j + b - 1;
if (p[i][j] > 0)
update(i, j, i1, j1, -p[i][j]);
else if (p[i][j] < 0)
ok = 0;
}
}
for (int i = n - a; i <= n && ok; i++)
{ //还原原数组
for (int j = m - b; j <= m && ok; j++)
{
p[i][j] += p[i - 1][j] + p[i][j - 1] - p[i - 1][j - 1];
if (p[i][j])
ok = 0;
}
}
if (ok)
cout << "^_^" << endl;
else
cout << "QAQ" << endl;
}
return 0;
}