1. 程式人生 > 實用技巧 >Web安全:你必須知道的“Cookie安全”

Web安全:你必須知道的“Cookie安全”

技術標籤:leetcode

貪心

每次都改變一行或者一列,將0和1互換
若干次操作之後,按照每行的數統計結果,用二進位制表示

首先高位的1會大於所有低位的1之和,如1000 = 8 > 0111 = 7
那麼我們貪心的策略就有了,其次為了儘可能的構造高位1,對於第一列,如果翻轉後1的個數多,那麼就翻轉,由於此時保證了最高位出現了最多的1,那麼我們接下來依次檢查每一行,如果這一行首尾不是0,那麼就翻轉這一行

然後我們用列變換再次檢查其它列的元素,如果翻轉後1變多,那麼翻轉列

總結一下策略

  1. 檢查第一列,如果翻轉後1變多,那麼翻轉
  2. 檢查每一行,如果高位不是1,那麼翻轉
  3. 檢查剩下的列(2到n),如果翻轉後1變多,那麼翻轉

一道很好的貪心題目

class Solution:
    def matrixScore(self, A: List[List[int]]) -> int:
            # 行和列
        row, col = len(A), len(A[0])
        # 統計第一列的1
        cnt = sum([A[i][0] for i in range(row)])
        # 如果翻轉後1變多
        if cnt <= row // 2:
            for i in range(row):
                A[
i][0] = 1 if A[i][0] == 0 else 0 # print(A) # 對於每一行,如果第一個元素不是1,翻轉這一行 for i in range(row): if A[i][0] != 1: for j in range(col): A[i][j] = 1 if A[i][j] == 0 else 0 # print(A) # 對於剩下的每一列,如果翻轉後1變多,那麼就翻轉 for j in
range(1, col): cnt = sum([A[i][j] for i in range(row)]) if cnt <= row // 2: for i in range(row): A[i][j] = 1 if A[i][j] == 0 else 0 # print(A) ans = 0 for i in range(row): inx = 2 for j in range(col - 1, -1, -1): ans += A[i][j] * (inx ** (col - j - 1)) return ans

再分析一下,我們要保證最高位都是1,那麼第一步檢查翻轉列就是多餘的,直接檢查每一行即可

class Solution:
    def matrixScore(self, A: List[List[int]]) -> int:
            # 行和列
        row, col = len(A), len(A[0])

        # 對於每一行,如果第一個元素不是1,翻轉這一行
        for i in range(row):
            if A[i][0] != 1:
                for j in range(col):
                    A[i][j] = 1 if A[i][j] == 0 else 0

        # print(A)

        # 對於剩下的每一列,如果翻轉後1變多,那麼就翻轉
        for j in range(1, col):
            cnt = sum([A[i][j] for i in range(row)])
            if cnt <= row // 2:
                for i in range(row):
                    A[i][j] = 1 if A[i][j] == 0 else 0

        # print(A)
        ans = 0
        for i in range(row):
            inx = 2
            for j in range(col - 1, -1, -1):
                ans += A[i][j] * (inx ** (col - j - 1))

        return ans

在這裡插入圖片描述

不用移動矩陣的貪心

主要是貪心策略加上一些trick,直接用二進位制的方法來統計每一位上1的貢獻

在這裡插入圖片描述

class Solution {
public:
    int matrixScore(vector<vector<int>>& A) {
        int m = A.size(), n = A[0].size();
        int ret = m * (1 << (n - 1));

        for (int j = 1; j < n; j++) {
            int nOnes = 0;
            for (int i = 0; i < m; i++) {
                if (A[i][0] == 1) {
                    nOnes += A[i][j];
                } else {
                    nOnes += (1 - A[i][j]); // 如果這一行進行了行反轉,則該元素的實際取值為 1 - A[i][j]
                }
            }
            int k = max(nOnes, m - nOnes);
            ret += k * (1 << (n - j - 1));
        }
        return ret;
    }
};

作者:LeetCode-Solution
連結:https://leetcode-cn.com/problems/score-after-flipping-matrix/solution/fan-zhuan-ju-zhen-hou-de-de-fen-by-leetc-cxma/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

思想就是最大的矩陣第一列肯定都是1,然後直接加上首位的貢獻,然後對於剩下的列,統計1的個數(如果首位是0,意味著這一行要反轉,需要對應操作),然後我們用位移的方法加上每個1的貢獻即可