27翻转矩阵后的得分(861)

作者: Turbo时间限制: 1S章节: 贪心

晚于: 2020-07-22 12:00:00后提交分数乘系数50%

截止日期: 2020-07-29 12:00:00

问题描述 :

有一个二维矩阵 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

输出说明 :

输出一个整数

输入范例 :

输出范例 :

class Solution 
{
public:
    int matrixScore(vector<vector<int>>& A) 
    {
        
        if(A.empty())
            return 0;
        int m=A.size(),n=A[0].size(); 
        for(int i=0;i<m;i++)//先把第一行的首字母变为1 
        {
            if(A[i][0]==0)
            {
                for(int j=0;j<n;j++)
                    A[i][j]^=1;
                
            }
        }
        int res=m*pow(2,n-1);//第一列全为1,res初始值、
        for(int j=1;j<n;j++) //按列计算1的个数 
        {
            int sum=0;
            for(int i=0;i<m;i++)
            {
                if(A[i][j]==1)
                    sum++; 
            }
            if(sum<=m/2)//计算机1的个数是否少于列的一半,其实就是列反转,只不过不真正的反转,直接计算个数 
                sum=m-sum;
            res+=sum*pow(2,n-j-1);
            
        }
    
    return res;
    }
};
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

class Solution 
{
public:
    int matrixScore(vector<vector<int>>& A) 
    {
        
        if(A.empty())
            return 0;
        int m=A.size(),n=A[0].size(); 
        for(int i=0;i<m;i++)//先把第一行的首字母变为1 
        {
            if(A[i][0]==0)
            {
                for(int j=0;j<n;j++)
                    A[i][j]^=1;
                
            }
        }
        int res=m*pow(2,n-1);//第一列全为1,res初始值、
        for(int j=1;j<n;j++) //按列计算1的个数 
        {
            int sum=0;
            for(int i=0;i<m;i++)
            {
                if(A[i][j]==1)
                    sum++; 
            }
            if(sum<=m/2)//计算机1的个数是否少于列的一半,其实就是列反转,只不过不真正的反转,直接计算个数 
                sum=m-sum;
            res+=sum*pow(2,n-j-1);
            
        }
    
    return res;
    }
};

int main()
{
    int m, n,data,k;
    vector<vector<int> > A;
    cin>>m>>n;
    for(int i=0; i<m; i++)
    {
        vector<int> row;
        for(int j=0; j<n; j++)
        {
            cin>>data;
            row.push_back(data);
        }
        A.push_back(row);
    }
    int res=Solution().matrixScore(A);
    cout<<res<<endl;
    return 0;
}
对于二进制数来说,我们只要保证最高位是1,就可以保证这个数是最大的,因为移动操作会使得它取反,因此我们进行行变化的时候只需要考虑首位即可。
对于后面的列处理,由于只影响的是该列,所以若要取得最大值,只需要保证该列1的个数 不少于0的个数即可。
但是我们在进行列判断的时候,可以简化移动操作,因为这个过程我们会进行记录1的个数的计算,所以我们可以直接由1个个数去计算最后的总和即可。
作者:er-zong
链接:https://leetcode-cn.com/problems/score-after-flipping-matrix/solution/c-4ms-by-er-zong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原文地址:https://www.cnblogs.com/zmmm/p/13623675.html