• 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)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    高级特性(4)- 数据库编程
    UVA Jin Ge Jin Qu hao 12563
    UVA 116 Unidirectional TSP
    HDU 2224 The shortest path
    poj 2677 Tour
    【算法学习】双调欧几里得旅行商问题(动态规划)
    南洋理工大学 ACM 在线评测系统 矩形嵌套
    UVA The Tower of Babylon
    uva A Spy in the Metro(洛谷 P2583 地铁间谍)
    洛谷 P1095 守望者的逃离
  • 原文地址:https://www.cnblogs.com/zmmm/p/13623675.html
Copyright © 2020-2023  润新知