问题描述 :
有一个二维矩阵 A ,其中每个元素的值为 0 或 1 。
翻转是指选择任一行或列,并转换该行或列中的每一个值:将所有 0 都更改为 1,将所有 1 都更改为 0。
在做出任意次数的翻转后,将该矩阵的每一行都按照二进制数来解释,矩阵的得分就是这些数字的总和。
返回尽可能高的分数。
示例:
输入:[[0,0,1,1],[1,0,1,0],[1,1,0,0]]
输出:39
解释:
转换为 [[1,1,1,1],[1,0,0,1],[1,1,1,1]]
0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
输入说明 :
首先输入矩阵的行数m、列数n,
然后输入m行,每行n个数字,每个数字都是0或1。
1 <= m <= 20
1 <= n <= 20
输出说明 :
输出一个整数
输入范例 :
3 4
0 0 1 1
1 0 1 0
1 1 0 0
输出范例 :
39
思路:
一个二进制数,只有最高位为1时才能取得最大值。
因此我们先翻转每行第一个元素为0的行,这样循环下来,第一列都为1
此时res = (1<<n-1)*m,这是第一列m个1的二进制和
接下来我们翻转剩余的n-1列,这里我们只要算出每列中0的个数和1的个数,得到cnt = max(0的个数,1的个数),则第j列cnt个1的二进制之和为(1<<(n-1-j))*cnt
#include<iostream>
#include<vector>
using namespace std;
class Solution{
public:
int matrixScore(vector<int> &A) {
int row = A.size(); //行
int col = A[0].size(); //列
for(int i = 0; i < row; i++) {
if(A[i][0]) {
continue;
}
for(int j = 0; j < col; j++) {
A[i][j] ^= 1;
}
}
int res = (1<<(col-1))*row; //第一列row个1的二进制之和
for(int j = 1; j < col; j++){
int cnt = 0;
for(int i = 0; i < row; i++) {
if(A[i][j]) {
cnt++;
}
}
cnt = max(cnt,row-cnt);
res += (1<<(col-1-j))*cnt;
}
return res;
}
};
int main() {
int m,n,data;
cin>>m>>n;
vector<vector<int> > A(m,vector<int>(n,0));
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
cin>>data;
A[i][j] = data;
}
}
Solution s;
int res = s.matrixScore(A);
cout<<res;
return 0;
}