[LOJ6030] 「雅礼集训 2017 Day1」矩阵 - 构造

Solution

如果整个矩阵中没有 \(1\),那么无法构造,输出 \(-1\)

以下讨论中我们假设矩阵中至少存在一个 \(1\)

先构造出一行,然后用这一行去填充所有不全为 \(1\) 的列,设不全为 \(1\) 的列的数目为 \(x\),则需要 \(x\) 次操作

考虑如何构造这一行

设我们要构造第 \(i\) 行,则能利用且仅能利用第 \(i\) 列上的 \(1\),设第 \(i\) 行中有 \(y\)\(0\),则需要操作 \(y\)

如果第 \(i\) 行的 \(y>0\) 而第 \(i\) 列中没有 \(1\),则需要额外引入一个 \(1\),花费 \(1\) 次操作

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1005;

char c[N][N];
int a[N][N], n, sum;

signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> c[i] + 1;
        for (int j = 1; j <= n; j++) {
            a[i][j] = c[i][j] == '#';
            sum += a[i][j];
        }
    }
    if (sum == 0) {
        cout << -1;
        return 0;
    }
    int x = 0;
    int ans = 1e9;
    for (int i = 1; i <= n; i++) {
        int tmp = 0;
        for (int j = 1; j <= n; j++) tmp += a[j][i];
        if (tmp < n)
            ++x;
    }
    for (int i = 1; i <= n; i++) {
        int y = 0;
        for (int j = 1; j <= n; j++) y += a[i][j] == 0;
        int s = 0;
        for (int j = 1; j <= n; j++) s += a[j][i];
        if (y && !s)
            ++y;
        ans = min(ans, y);
    }
    cout << ans + x << endl;
}

相关文章: