1. 程式人生 > 實用技巧 >2020-12-7 翻轉矩陣後的得分

2020-12-7 翻轉矩陣後的得分

題目


解題思路

本題的目標是通過多次行或列的反轉,以使得陣列中各行所表示的二進位制數的值之和最大。
經分析可知,要使和最大,須優先使得列下標值較小的列中1的個數最多。所以得到如下思路:

  1. 通過行反轉使得第一列的所有元素均為1(即每行的第一個元素均為1)
  2. 然後遍歷除第一列外的每一列,求出每列中1的個數,若其小於行數的一半,便對該列進行反轉。
  3. 最後對得到的最佳矩陣求和。

程式碼實現

class Solution {
public:
    int matrixScore(vector<vector<int>>& A) {
        vector<int> cnt(A[0].size()-1, 0);

        // 使每行的第一個元素都變為1
        for (int i = 0; i < A.size(); i++){
            if (A[i][0] == 0)
                reverseArr(A[i]);
        } 

        // 遍歷除第一列外的元素,記錄各列為1的個數儲存入陣列cnt
        for (int j = 1; j < A[0].size(); j++){
            for (int i = 0; i < A.size(); i++){
                if (A[i][j] == 1)
                    cnt[j-1]++;
            }
			
            if (cnt[j-1] < A.size()/2+1){
                for (int i = 0; i < A.size(); i++){
                    A[i][j] ^= 1; 
                }
                cnt[j-1] = A.size() - cnt[j-1];
            }
        }

        // 求和
        int sum = A.size() * pow(2, A[0].size()-1);
        for (int i = 1; i < A[0].size(); i++)
            sum += cnt[i-1] * pow(2, A[0].size()-i-1);
    
        return sum;
    }

    void reverseArr(vector<int>& arr){
        for (int i = 0; i < arr.size(); i++)
            arr[i] ^= 1;
    }
};

提交結果