我们称一个矩阵为黑白矩阵,当且仅当对于该矩阵中每一个位置如(i, j),其上下左右四个方向的数字相等,即(i-1, j)、(i+1, j)、(i, j-1)、(i, j+1)四个位置上的数字两两相等且均不等于(i, j)位置上的数字。(超出边界的格子忽略)
现在给出一个 n*m 的矩阵,我们想通过修改其中的某些数字,使得该矩阵变成黑白矩阵,请问最少需要修改多少个数字。
输入格式
第一行包含两个整数n和m,表示矩阵的长宽。
接下来n行,每行包含m个整数,用来表示整个矩阵。
输出格式
仅包含一个整数,表示原矩阵变为黑白矩阵最少修改的数字数量。
数据范围
105
输入样例1:
3 3 1 1 1 1 1 1 1 1 1
输出样例1:
4
输入样例2:
3 3 1 1 1 1 5 1 1 1 1
输出样例2:
4 所有奇数格的数相等 && 所有偶数格的数相等 && 奇数格上的数不等于偶数格的数记录奇数格上每个数字出现的个数 同样记录偶数格上每个数字出现的个数若奇数格和偶数格出现次数最多的数字相等 比较出现次数第二多的数字所以枚举4种情况 x1 y1 、 x1 y2 、 x2 y1 、 x2 y2(不可能出现)
#include <iostream> #include <algorithm> #include <unordered_map> #include <vector> using namespace std; typedef pair<int, int> PII; int main() { int n, m; cin >> n >> m; unordered_map<int, int> AS, BS; for (int i = 0; i < n; i ++ ) for (int j = 0; j < m; j ++ ) { int x; cin >> x; if ((i + j) % 2) AS[x] ++ ; else BS[x] ++ ; } vector<PII> A, B; for (auto item : AS) A.push_back({item.second, item.first}); for (auto item : BS) B.push_back({item.second, item.first}); sort(A.begin(), A.end()), reverse(A.begin(), A.end()); sort(B.begin(), B.end()), reverse(B.begin(), B.end()); int res = 0; for (int i = 0; i < 2 && i < A.size(); i ++ ) for (int j = 0; j < 2 && j < B.size(); j ++ ) if (A[i].second == B[j].second) res = max(res, max(A[i].first, B[j].first)); else res = max(res, A[i].first + B[j].first); if (A.empty()) res = B[0].first; if (B.empty()) res = A[0].first; cout << n * m - res << endl; return 0; }
来源:https://www.cnblogs.com/kelly1895/p/10816315.html