版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/qq_41855420,未经博主允许不得转载。 https://blog.csdn.net/qq_41855420/article/details/91127810
有一个二维矩阵 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
提示:
1 <= A.length <= 20
1 <= A[0].length <= 20
A[i][j] 是 0 或 1
这道题说白了就是让我们计算矩阵所有元素的和,并且每个元素是有一定的权重。
并且可知每一行的第一个元素的权重最大,且由于二进制的特征,最高位的1权值会超过低位所有权值的和,比如“11111”,最高位的’1’代表24 = 16,第四位"1111" = 2 3 + 2 2 + 2 1 + 20 = 15。
因此我们首先需要保证第一列(每一行的第一个元素)都为1,
我们第一步判断每一行的第一个元素是否是1,如果不是1,则将这一行的所有元素进行翻转;
第二步:尽量保证剩余列中1的个数竟可能多。
class Solution {
public:
int matrixScore(vector<vector<int>>& A) {
int sumRes = 0;
int rowSize = A.size(), colSize = A[0].size();
//首先保证第一列全部为1
for (int row = 0; row < rowSize; ++row){
if (A[row][0] != 1){
//如果这一行的第一个元素不为1,则翻转这一行
for (int col = 0; col < colSize; ++col){
A[row][col] = 1 - A[row][col];
}
}
}
//第一列全为1,所以可以直接求第一列的权值和
sumRes += rowSize * pow(2, colSize - 1);
//再使其他列中1的个数尽可能多
for (int col = 1; col < colSize; ++col){
int oneCount = 0;//统计这一列1的个数
for (int row = 0; row < rowSize; ++row){
oneCount += A[row][col];
}
if (oneCount * 2 >= rowSize){
//如果1的个数不少于一般,则这一列不需要翻转
sumRes += oneCount * pow(2, colSize - col - 1);
}
else{
//否则将计算这一列进行翻转之后1的个数的权值和
sumRes += (rowSize - oneCount) * pow(2, colSize - col - 1);
}
}
return sumRes;
}
};