W
H
X

CF1157G Inverse of Rows and Columns

题面

当n>1时,为了满足题目的条件,最后的矩阵必须满足两个条件中至少一个:A、第一行全是0 B、最后一行全是1

按照两种情况做两遍(强制使其中一个情况满足)就可以得到答案了吧,以A为例:

若a[1][i]=1,则第i列标记为需要一次操作,然后对之后每一行判断操作后的情况

有两种情况存在答案:

1、对a[1][i]=1的列操作一次后,所有行都只包含0或1,此时可选择将所有行都翻成只有0(或只有1)

2、仅有一行k同时包含0和1,且0和1都挤在一堆(左边一堆0,右边一堆1或左边一堆1,右边一堆0),对于1都在左边的情况对第k行操作一次,然后1——k-1行都翻成0,k+1——n行都翻成1

然后以类似方法对B操作一次,如果两种都不能得出答案print(-1)

#include <bits/stdc++.h>
using namespace std;
inline void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
} int n, m, a[238][238], x[238], y[238];
signed main() {
    read (n), read (m);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j) read (a[i][j]);
    if (n == 1) {
        puts ("YES"); puts ("0");
        for (int i = 1; i <= m; ++i)
            a[1][i] ? putchar (48) : putchar (49);
        return 0;
    } if (m == 1) {
        puts ("YES");
        for (int i = 1; i <= n; ++i)
            a[i][1] ? putchar (48) : putchar (49); puts ("");
        return putchar (48), 0;
    }
    //第一种:让第一行全变为 0
    int ok = 1, cnt = 0, w, qwq;
    for (int i = 1; i <= m; ++i) y[i] = a[1][i];
    for (int i = 2; i <= n; ++i) {
        int tmp = 0;
        for (int j = 2; j <= m; ++j)
            if ((a[i][j] ^ y[j]) != (a[i][j - 1] ^ y[j - 1])) ++tmp, qwq = (a[i][j] ^ y[j]);
        if (tmp) {
            cnt += tmp, w = i;
            if (cnt > 1) { ok = 0; break; }
        }
    } if (ok) {
        puts ("YES");
        if (cnt) {
            for (int i = 2; i < w; ++i) x[i] = a[i][1] ^ y[1]; x[w] = qwq ^ 1;
            for (int i = w + 1; i <= n; ++i) x[i] = a[i][1] ^ y[1] ^ 1;
        } else for (int i = 2; i <= n; ++i) x[i] = a[i][1] ^ y[1];
        for (int i = 1; i <= n; ++i) putchar (x[i] + 48); puts ("");
        for (int i = 1; i <= m; ++i) putchar (y[i] + 48); return 0;
    }
    //第二种:让第二行全变为 1
    ok = 1, cnt = 0;
    for (int i = 1; i <= m; ++i) y[i] = a[n][i] ^ 1;
    for (int i = 1; i < n; ++i) {
        int tmp = 0;
        for (int j = 2; j <= m; ++j)
            if ((a[i][j] ^ y[j]) != (a[i][j - 1] ^ y[j - 1])) ++tmp, qwq = (a[i][j] ^ y[j]);
        if (tmp) {
            cnt += tmp, w = i;
            if (cnt > 1) { ok = 0; break; }
        }
    } if (ok) {
        puts ("YES");
        if (cnt) {
            for (int i = 1; i < w; ++i) x[i] = a[i][1] ^ y[1]; x[w] = qwq ^ 1;
            for (int i = w + 1; i < n; ++i) x[i] = a[i][1] ^ 1 ^ y[1];
        } else for (int i = 1; i < n; ++i) x[i] = a[i][1] ^ y[1];
        for (int i = 1; i <= n; ++i) putchar (x[i] + 48); puts ("");
        for (int i = 1; i <= m; ++i) putchar (y[i] + 48); return 0;
    } return puts ("NO"), 0;
}
posted @ 2020-04-10 19:43  -敲键盘的猫-  阅读(241)  评论(0编辑  收藏  举报