「解题报告」[省选联考 2021 A 卷] 矩阵游戏

啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!啥都不会了!

考虑随便构造出来一个矩阵 \(A\),考虑调整使得答案合法。

根据 经 典 ,发现对一行或一列进行 \(+1,-1,+1,-1,\cdots\) 不会改变 \(B\) 矩阵,并且所有可能的 \(A\) 都可以用这种操作搞出来。

那么先令 \(i + j\) 为奇数的位置的 \(A_{i, j} \gets V - A_{i, j}\),其中 \(V\) 为值域,即 \(10^6\),那么久相当于变成了对一行或一列加一个数或减一个数了。

发现相当于要求两个数组 \(x_i, y_i\),满足 \(0 \le a_{i, j} + x_i + y_j \le V\)

发现很像差分约束,所以把 \(y_i\) 取个负数,移项即可,然后跑差分约束即可。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 605, V = 1000000;
int T, n, m;
int b[MAXN][MAXN];
long long a[MAXN][MAXN];
int x[MAXN], y[MAXN], ncnt;
long long dis[MAXN];
int cnt[MAXN];
bool inStack[MAXN];
vector<pair<int, long long>> e[MAXN];
bool spfa() {
    memset(dis, 0x3f, sizeof dis);
    memset(cnt, 0, sizeof cnt);
    memset(inStack, false, sizeof inStack);
    queue<int> q;
    dis[1] = 0, q.push(1);
    while (!q.empty()) {
        int u = q.front(); q.pop();
        if (cnt[u] > ncnt) return false;
        cnt[u]++;
        inStack[u] = false;
        for (auto p : e[u]) {
            int v = p.first; long long w = p.second;
            if (dis[v] > dis[u] + w) {
                dis[v] = dis[u] + w;
                if (!inStack[v]) {
                    inStack[v] = 1;
                    q.push(v);
                }
            }
        }
    }
    return true;
}
int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d%d", &n, &m);
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < m; j++) {
                scanf("%d", &b[i][j]);
            }
        }
        memset(a, 0, sizeof a);
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < m; j++) {
                a[i + 1][j + 1] = b[i][j] - a[i][j] - a[i][j + 1] - a[i + 1][j];
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if ((i + j) & 1) {
                    a[i][j] = V - a[i][j];
                }
            }
        }
        ncnt = 0;
        for (int i = 1; i <= n; i++) {
            x[i] = ++ncnt;
        }
        for (int j = 1; j <= m; j++) {
            y[j] = ++ncnt;
        }
        for (int i = 1; i <= ncnt; i++) {
            e[i].clear();
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                e[x[i]].push_back({y[j], a[i][j]});
                e[y[j]].push_back({x[i], V - a[i][j]});
            }
        }
        if (!spfa()) {
            printf("NO\n");
            continue;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                a[i][j] += dis[x[i]] - dis[y[j]];
            }
        }
        printf("YES\n");
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if ((i + j) & 1) {
                    a[i][j] = V - a[i][j];
                }
                printf("%lld ", a[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}
posted @ 2023-02-11 18:10  APJifengc  阅读(52)  评论(0编辑  收藏  举报