2020 ICPC小米 网络选拔赛第一场 J - Matrix Subtraction (二维差分)

Intelligent Warehouse

题目大意:

给一个\(n \times m\)的矩阵和一个\(a \times b\)的单位矩阵,然后在\(n \times m\)的矩阵中任取\(a \times 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;
}
posted @ 2020-11-10 17:18  Nepenthe8  阅读(72)  评论(0编辑  收藏  举报