他想知道自己最少需要几次操作可以做到,或者永远无法做到,请你帮帮他吧。
每个测试文件均包含多个测试点。第一行输入一个整数代表测试数据组数,每组测试数据描述如下:
第一行输入一个,表示方阵的长和宽。
此后行,每行输入
个整数(保证为 0 或者 1),表示方阵
。
此后行,每行输入
个整数(保证为 0 或者 1),表示方阵
。
对于每组测试数据,在一行上输出一个整数表示最少的操作次数,如果无法将变为
,输出
2 2 0 1 1 0 1 0 0 1 2 0 1 1 1 0 0 0 0
2 -1
第一个测试数据:
0 1
1 0
操作一次第一行变成:
1 0
1 0
再操作第二行变成:
1 0
0 1
因此最少需要 2 次。
#include <iostream>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
// 判断两个矩阵是否完全相同
bool isSame(const vector<vector<int>>& A, const vector<vector<int>>& B) {
int n = A.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (A[i][j] != B[i][j]) {
return false;
}
}
}
return true;
}
// 判断两个矩阵的指定行是否相同
bool isSameRow(const vector<vector<int>>& A, const vector<vector<int>>& B, int row_idx) {
int n = A.size();
for (int j = 0; j < n; j++) {
if (A[row_idx][j] != B[row_idx][j]) {
return false;
}
}
return true;
}
// 统计矩阵中1的个数
int count_1(const vector<vector<int>>& A) {
int n = A.size();
int num_1 = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (A[i][j] == 1) {
num_1++;
}
}
}
return num_1;
}
int min_op_counts(const vector<vector<int>>& A, const vector<vector<int>>& B) {
int n = A.size();
if (n == 1) {
if (A[0][0] == B[0][0]) {
return 0;
} else {
return 1;
}
} else if (n >= 2) { // 2^4 = 16()
if (isSame(A, B)) return 0;
else if (n != 3) {
int min_count = 0;
if (count_1(A) % 2 == 1) return -1;
if (count_1(B) % 2 == 1) return -1;
// 逐行对比,默认可以通过一次反转就相等,那么min_count+1
for (int row_idx = 0; row_idx < n; row_idx++) {
if (isSameRow(A, B, row_idx)) {
// 不操作当前行
} else {
min_count++; // 反转当前行
}
}
return min_count;
}
}
return -1;
}
int main() {
int T;
cin >> T;
for (int t = 0; t < T; t++) {
int n;
cin >> n;
vector<vector<int>> A(n, vector<int>(n));
vector<vector<int>> B(n, vector<int>(n));
// 输入矩阵A
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> A[i][j];
}
}
// 输入矩阵B
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> B[i][j];
}
}
cout << min_op_counts(A, B) << endl;
}
return 0;
}