Matrix Transformation
Brute force 启动!
首先,显而易见的是按二进制每一位进行拆分,接下来就是在 01 矩阵上操作。
定义一回合为:先扫描每一行,再扫描每一列,若该行/列有需要操作的就对整行/列进行操作。我们可以大胆猜测:若存在解,每次操作应该能固定一行与一列,因此最多会进行 次操作。我们完所有操作后判断是否达到目标状态即可。
赛场上我选择了 ,喜提 999 ms,险些被 hack。赛后实践得 就足够了。
单组数据时间复杂度 。
#include <algorithm>
#include <array>
#include <bitset>
#include <cstddef>
#include <iostream>
#include <ranges>
#include <vector>
using namespace std;
istream& fin = cin;
ostream& fout = cout;
using ui = unsigned int;
using uli = unsigned long long int;
using li = long long int;
int main(void) {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
size_t T;
fin >> T;
while (T--) {
size_t n, m;
fin >> n >> m;
vector a(n, vector<ui>(m)), b(n, vector<ui>(m));
for (auto& i : a)
for (auto& j : i) fin >> j;
for (auto& i : b)
for (auto& j : i) fin >> j;
for (size_t t = 0; t < 32; ++t) {
vector sa(n, vector<bool>(m)), sb(n, vector<bool>(m));
for (size_t i = 0; i < n; ++i)
for (size_t j = 0; j < m; ++j)
sa[i][j] = (a[i][j] >> t) & 1, sb[i][j] = (b[i][j] >> t) & 1;
for (size_t c = 0; c <= min(n, m); ++c) {
for (size_t i = 0; i < n; ++i) {
bool operate = false;
for (size_t j = 0; j < m; ++j)
if (sa[i][j] == 1 && sb[i][j] == 0) {
operate = true;
break;
}
if (operate)
for (size_t j = 0; j < m; ++j) sa[i][j] = 0;
}
for (size_t j = 0; j < m; ++j) {
bool operate = false;
for (size_t i = 0; i < n; ++i)
if (sa[i][j] == 0 && sb[i][j] == 1) {
operate = true;
break;
}
if (operate)
for (size_t i = 0; i < n; ++i) sa[i][j] = 1;
}
}
if (sa != sb) {
fout << "No\n";
goto end;
}
}
fout << "Yes\n";
end:;
}
return 0;
}