翻转矩阵后的得分

问题描述

有一个二维矩阵 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,然后让每列的1尽可能的多。

1、让每行第一个元素不为1的行反转。

2、行处理完之后,遍历除了第一列的所有列,判断此时每列1的个数,若1的个数小于0的个数则进行反转。

实现代码
#include<iostream>

#include<vector>

#include<math.h>

#include<algorithm>

using namespace std;


int fun(vector<vector<int>> &num){
    int res = 0;
    if(num.size() == 0) return res;

    int m = num.size();
    int n = num[0].size();

    //行变后
    res = m * pow(2,n - 1);//第一列都变1

    //处理除了第一列以外的列
    for(int i = 1;i<n;i++){
        int tem = 0;//记录1的个数
        for(int j = 0;j<m;j++){
            if(num[j][0] == 1){//该行的第一个元素本来就为1,所以该行没有反转,此时对应列的值就是原本的值
                tem += num[j][i];
            }else{//该行第一个元素原本为0,进行反转后,对应列的值会变化,0变1,1变0(此时用1-num[j][i]就是反转后的值)
                tem += (1 - num[j][i]);
            }
        }
        int k = max(tem,m - tem);
        res += k * pow(2,n - i - 1);
    }

    return res;



}

int main()

{

    int m,n,temp;
    cin>>m>>n;

    vector<vector<int>> num;
    vector<int> temps;

    for(int i = 0;i<m;i++){
        temps.clear();
        for(int j = 0;j<n;j++){
            cin>>temp;
            temps.push_back(temp);
        }
        num.push_back(temps);

    }

    int res = fun(num);
    cout<<res;


    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值