zoukankan      html  css  js  c++  java
  • 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)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    [CSP-S模拟测试]:Merchant(二分答案)
    [CSP-S模拟测试]:回文(hash+二维前缀和)
    [CSP-S模拟测试]:排列组合(数学 or 找规律)
    [CSP-S模拟测试]:X国的军队(贪心)
    BZOJ3714 [PA2014]Kuglarz 【最小生成树】
    BZOJ3922 Karin的弹幕 【线段树】
    BZOJ3495 PA2010 Riddle 【2-sat】
    BZOJ2597 [Wc2007]剪刀石头布 【费用流】
    hdu6184 Counting Stars 【三元环计数】
    BZOJ4815 [CQOI2017]小Q的表格 【数论 + 分块】
  • 原文地址:https://www.cnblogs.com/zmmm/p/13623675.html
Copyright © 2011-2022 走看看