📜  通过一次过滤子矩阵来最大化二进制矩阵

📅  最后修改于: 2021-09-17 16:02:02             🧑  作者: Mango

给定一个RC列的二进制矩阵。我们可以翻转到任何大小的子矩阵。翻转意味着将 1 更改为 0,将 0 更改为 1。任务是最大化矩阵中 1 的数量。输出最大数量的 1s。
例子:

Input : R = 3, C =3
mat[][] = { 0, 0, 1,
            0, 0, 1,
            1, 0, 1 }

Output : 8
Flip
0 0 1
0 0 1
1 0 1

to get

1 1 1
1 1 1
0 1 1

Input : R = 2, C = 3
mat[][] = { 0, 0, 0,
            0, 0, 0 }
Output : 6

创建一个 R 行 C 列的矩阵 ones[][],它预先计算子矩阵中从 (0, 0) 到 (i, j) 的数

// Common elements in ones[i-1][j] and 
// ones[i][j-1] are ones[i-1][j-1]
ones[i][j] = ones[i-1][j] + ones[i][j-1] - 
             ones[i-1][j-1] + (mat[i][j] == 1)

因为,我们只允许翻转子矩阵一次。我们对每个单元格 (i, j) 到 (i + k – 1, i + k – 1) 的所有可能大小的所有可能子矩阵进行迭代。我们计算在所选子矩阵中填充数字后的总数。
将子矩阵 (i, j) 翻转为 (i + k – 1) 后,最终矩阵中 1 的总数将为整个矩阵中的 1 – 所选子矩阵中的 1 + 所选子矩阵中的零。结果是:-
个[R][C] – cal(i, j, i + k, j + k – 1) + k*k – cal(i, j, i + k – 1, j + k – 1)
其中 cal(a, b, c, d) 表示长度为 c – a 的方阵子矩阵中 1 的个数。
现在 cal(x1, y1, x2, y2) 可以定义为:
个[x2][y2] – 个[x2][y1 – 1] – 个[x1 – 1][y2] + 个[x1 – 1][y1 – 1]。
下面是这个方法的实现:

C++
// C++ program to find maximum number of ones after
// one flipping in Binary Matrix
#include 
#define R 3
#define C 3
using namespace std;
 
// Return number of ones in square submatrix of size
// k x k starting from (x, y)
int cal(int ones[R + 1][C + 1], int x, int y, int k)
{
    return ones[x + k - 1][y + k - 1] - ones[x - 1][y + k - 1]
           - ones[x + k - 1][y - 1] + ones[x - 1][y - 1];
}
 
// Return maximum number of 1s after flipping a submatrix
int sol(int mat[R][C])
{
    int ans = 0;
 
    // Precomputing the number of 1s
    int ones[R + 1][C + 1] = {0};
    for (int i = 1; i <= R; i++)
        for (int j = 1; j <= C; j++)
            ones[i][j] = ones[i - 1][j] + ones[i][j - 1] -
                         ones[i - 1][j - 1] +
                         (mat[i - 1][j - 1] == 1);
 
    // Finding the maximum number of 1s after flipping
    for (int k = 1; k <= min(R, C); k++)
        for (int i = 1; i + k - 1 <= R; i++)
            for (int j = 1; j + k - 1 <= C; j++)
                ans = max(ans, (ones[R][C] + k * k -
                                2 * cal(ones, i, j, k)));
    return ans;
}
 
// Driver code
int main()
{
    int mat[R][C] = {{0, 0, 1},
        { 0, 0, 1},
        { 1, 0, 1 }
    };
 
    cout << sol(mat) << endl;
 
    return 0;
}


Java
// Java program to find maximum number of ones after
// one flipping in Binary Matrix
class GFG {
 
static final int R = 3;
static final int C = 3 ;
 
 
// Return number of ones in square submatrix of size
// k x k starting from (x, y)
static int cal(int ones[][], int x, int y, int k)
{
    return ones[x + k - 1][y + k - 1] - ones[x - 1][y + k - 1]
        - ones[x + k - 1][y - 1] + ones[x - 1][y - 1];
}
 
// Return maximum number of 1s after flipping a submatrix
static int sol(int mat[][])
{
    int ans = 0;
        int val =0;
    // Precomputing the number of 1s
    int ones[][] = new int[R + 1][C + 1];
    for (int i = 1; i <= R; i++)
        for (int j = 1; j <= C; j++) {
                    if(mat[i - 1][j - 1] == 1)
                        val=1;
        ones[i][j] = ones[i - 1][j] + ones[i][j - 1] -
                        ones[i - 1][j - 1] +
                        (val);
                }
    // Finding the maximum number of 1s after flipping
    for (int k = 1; k <= Math.min(R, C); k++)
        for (int i = 1; i + k - 1 <= R; i++)
            for (int j = 1; j + k - 1 <= C; j++)
                ans = Math.max(ans, (ones[R][C] + k * k -
                                2 * cal(ones, i, j, k)));
    return ans;
}
 
// Driver code
    static public void main(String[] args) {
        int mat[][] = {{0, 0, 1},
        { 0, 0, 1},
        { 1, 0, 1 }
    };
 
       System.out.println(sol(mat));
    }
}
 
// This code is contributed by Rajput-Ji


Python3
# Python 3 program to find maximum number of
# ones after one flipping in Binary Matrix
R = 3
C = 3
 
# Return number of ones in square submatrix
# of size k x k starting from (x, y)
def cal(ones, x, y, k):
    return (ones[x + k - 1][y + k - 1] -
            ones[x - 1][y + k - 1] -
            ones[x + k - 1][y - 1] +
            ones[x - 1][y - 1])
 
# Return maximum number of 1s after
# flipping a submatrix
def sol(mat):
    ans = 0
 
    # Precomputing the number of 1s
    ones = [[0 for i in range(C + 1)]
               for i in range(R + 1)]
    for i in range(1, R + 1, 1):
        for j in range(1, C + 1, 1):
            ones[i][j] = (ones[i - 1][j] + ones[i][j - 1] -
                          ones[i - 1][j - 1] +
                         (mat[i - 1][j - 1] == 1))
 
    # Finding the maximum number of 1s
    # after flipping
    for k in range(1, min(R, C) + 1, 1):
        for i in range(1, R - k + 2, 1):
            for j in range(1, C - k + 2, 1):
                ans = max(ans, (ones[R][C] + k * k - 2 *
                            cal(ones, i, j, k)))
    return ans
 
# Driver code
if __name__ == '__main__':
    mat = [[0, 0, 1],
           [0, 0, 1],
           [1, 0, 1]]
 
    print(sol(mat))
 
# This code is contributed by
# Sahil_Shelangia


C#
// C# program to find maximum number of ones after
// one flipping in Binary Matrix
using System;   
 
public class GFG {
 
    static readonly int R = 3;
    static readonly int C = 3 ;
 
 
    // Return number of ones in square submatrix of size
    // k x k starting from (x, y)
    static int cal(int [,]ones, int x, int y, int k)
    {
        return ones[x + k - 1,y + k - 1] - ones[x - 1,y + k - 1]
            - ones[x + k - 1,y - 1] + ones[x - 1,y - 1];
    }
 
    // Return maximum number of 1s after flipping a submatrix
    static int sol(int [,]mat)
    {
        int ans = 0;
            int val =0;
        // Precomputing the number of 1s
        int [,]ones = new int[R + 1,C + 1];
        for (int i = 1; i <= R; i++)
            for (int j = 1; j <= C; j++) {
                        if(mat[i - 1,j - 1] == 1)
                            val=1;
            ones[i,j] = ones[i - 1,j] + ones[i,j - 1] -
                            ones[i - 1,j - 1] +
                            (val);
                    }
        // Finding the maximum number of 1s after flipping
        for (int k = 1; k <= Math.Min(R, C); k++)
            for (int i = 1; i + k - 1 <= R; i++)
                for (int j = 1; j + k - 1 <= C; j++)
                    ans = Math.Max(ans, (ones[R,C] + k * k -
                                    2 * cal(ones, i, j, k)));
        return ans;
    }
 
    // Driver code
    static public void Main() {
        int [,]mat = {{0, 0, 1},
        { 0, 0, 1},
        { 1, 0, 1 }
    };
 
    Console.WriteLine(sol(mat));
    }
}
// This code is contributed by 29AjayKumar


PHP


Javascript


输出:

8

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程