玄学正确 or 数据太水
查看原帖
玄学正确 or 数据太水
982513
EternalHeart1314楼主2024/7/21 13:34

一种玄学做法,A了:

每一行每一列都有一个状态,为 nono 或 yesyes,一开始全为 nono。

若某一行或某一列只有一个 11,设这个 11 的位置在 (i,j)(i,j)(即第 ii 行第 jj 列),则把第 ii 行和第 jj 列的值全设为 00,并且把第 ii 行和第 jj 列的状态设为 yesyes。

重复以上操作直到每一行且每一列的 11 的个数都不等于 11(即只能为 00 或大于 11)。

然后若 (i,j)(i,j) 这个位置为 11,则把第 ii 行和第 jj 列的状态设为 yesyes。

最后判断:每一行每一列的状态都为 yesyes,则输出 YesYes,否则输出 NoNo。

CodeCode:

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

const int N = 2e2 + 7;
int t, n, flg, ok, fx[N], fy[N];
set<int> x[N], y[N];

main() {
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= n; ++i) fx[i] = fy[i] = 0, x[i].clear(), y[i].clear();
        flg = ok = 1;
        for (int i = 1, in; i <= n; ++i) for (int j = 1; j <= n; ++j) {
        cin >> in;
            if (in) x[i].insert(j), y[j].insert(i);
        }
        while (ok) {
            ok = 0;
            for (int i = 1; i <= n; ++i) if (x[i].size() == 1) {
                fy[*x[i].begin()] = fx[i] = ok = 1;
                for (auto j : y[*x[i].begin()]) if (i != j && x[j].find(*x[i].begin()) != x[j].end()) x[j].erase(x[j].find(*x[i].begin()));
                y[*x[i].begin()].clear(), x[i].clear();
            }
            for (int i = 1; i <= n; ++i) if (y[i].size() == 1) {
                fx[*y[i].begin()] = fy[i] = ok = 1;
                for (auto j : x[*y[i].begin()]) if (i != j && y[j].find(*y[i].begin()) != y[j].end()) y[j].erase(y[j].find(*y[i].begin()));
                x[*y[i].begin()].clear(), y[i].clear();
            }
        }
        for (int i = 1; i <= n; ++i) if (x[i].size()) {
            fx[i] = 1;
            for (auto j : x[i]) fy[j] = 1;
        }
        for (int i = 1; i <= n; ++i) flg &= fx[i];
        for (int i = 1; i <= n; ++i) flg &= fy[i];
        cout << (flg ? "Yes\n" : "No\n");
    }
    return 0;
}
2024/7/21 13:34
加载中...