版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014573686/article/details/89483333
题目
修改矩阵中的数字,使其成为黑白矩阵。即: (i,j)位置元素的上下左右都两两相同,但是与其不同。不在矩阵范围内的上下左右不考虑。
输入:n,m n行元素,每行m个
输出:修改次数,是一个值
输入示例:
3 3
1 1 1
1 5 1
1 1 1
输出:
4
思路
变成黑白矩阵,矩阵中最后只有两种数字,即一种黑,一种白
结果就是圆圈的位置是一种,可以叫做黑,三角的位置是一种,可以叫做白。
根据图可以得到规律,当 行号 % 2 == 列号 % 2 时是一种,否则是另一种,这样就可以得到黑数组和白数组。
要使黑数组中的数全部变成相同的,那么保留重复次数最多的数,修改其他的数,白数组同理。
矩阵的总数 减去 两个重复最多次数的和就是需要修改的次数。
比如 3 * 3的矩阵,黑数组 5 个元素,有3个相同的,那么需要修改的次数就是 2
白数组 4 个元素,有 3 个相同的,那么需要修改的次数就是 1
当这两个数组重复的数不是相同的,比如 黑数组中 3 重复次数最多,白数组 1 重复次数最多,那么直接用矩阵总数 9 减去
黑数组重复元素次数 3 再减去 白数组重复次数 3 结果就是 3
另一种情况,如果黑白数组重复次数最多的元素相同,比如都是 1 重复次数最多, 那么就需要求出黑白数组的第二重复最多的次数a2, b2
然后 a1 + b2 和 a2 + b1哪个大,最终就减去哪个(a1 是黑数组重复次数第一多的,b1是白数组重复次数第一多的)
具体见代码:
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
// 修改矩阵中的数字,使其变为黑白矩阵,即某元素的上下左右元素都相同,且与此元素不同。求最小的修改次数
// 存储最大重复次数的值和次数
typedef struct MaxPair
{
int time;
int val;
};
// 找到最大重复次数和值
MaxPair findMaxPair(unordered_map<int, int> mp)
{
unordered_map<int, int>::iterator iter = mp.begin();
MaxPair maxP;
maxP.time = 0;
//int max = 0;
for (; iter != mp.end(); iter++)
{
if (iter->second >= maxP.time)
{
maxP.time = iter->second;
maxP.val = iter->first;
}
}
return maxP;
}
// 找到除某个数外,其余数中重复次数最大的数
MaxPair findMaxPairEK(unordered_map<int, int> mp, int k)
{
unordered_map<int, int>::iterator iter = mp.begin();
MaxPair maxP;
maxP.time = 0;
//int max = 0;
for (; iter != mp.end(); iter++)
{
if (iter->second >= maxP.time && iter->first != k)
{
maxP.time = iter->second;
maxP.val = iter->first;
}
}
return maxP;
}
int main()
{
int m, n;
int val;
cin >> m >> n;
vector<vector<int>> arr;
for (int i = 0; i < n; i++)
{
vector<int> sArr;
for (int j = 0; j < m; j++)
{
cin >> val;
sArr.push_back(val);
}
arr.push_back(sArr);
}
vector<int> black;
vector<int> white;
// 黑白数组初始化
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (i % 2 == j % 2)
{
black.push_back(arr[i][j]);
}
else
{
white.push_back(arr[i][j]);
}
}
}
// 计算重复数的最大值
unordered_map<int, int> aMap;
unordered_map<int, int> wMap;
// 键值对存储重复次数
unordered_map<int, int>::iterator iter;
for (int i = 0; i < black.size(); i++)
{
// 有了
if ((iter = aMap.find(black[i])) != aMap.end())
{
(iter->second)++;
}
else
{
aMap[black[i]] = 1;
}
}
for (int i = 0; i < white.size(); i++)
{
// 有了
if ((iter = wMap.find(white[i])) != wMap.end())
{
(iter->second)++;
}
else
{
wMap[white[i]] = 1;
}
}
// 找最大值
int result = 0;
MaxPair amaxp = findMaxPair(aMap);
MaxPair wmaxp = findMaxPair(wMap);
if (amaxp.val != wmaxp.val)
{
result = black.size() - amaxp.time;
result += (white.size() - wmaxp.time);
}
else
{
int a1, b1, a2, b2;
a1 = wmaxp.time;
b1 = amaxp.time;
a2 = findMaxPairEK(aMap, amaxp.val).time;
b2 = findMaxPairEK(wMap, amaxp.val).time;
int max = (a1 + b2) > (a2 + b1) ? (a1 + b2) : (a2 + b1);
result = black.size() + white.size() - max;
}
cout << result;
//system("pause");
return 0;
}
如有问题还望指出