给定尺寸为M x N的Q和二进制查询形式为( x1,y1,x2,y2)的二进制矩阵arr [] [] ,其中( x1,y1 )和( x2,y2 )分别表示左上和子矩阵的右索引分别需要翻转(将0s转换为1s,反之亦然)。任务是打印执行给定的Q查询后获得的最终矩阵
例子:
Input: arr[][] = {{0, 1, 0}, {1, 1, 0}}, queries[][] = {{1, 1, 2, 3}}
Output: [[1, 0, 1], [0, 0, 1]]
Explanation:
The submatrix to be flipped is equal to {{0, 1, 0}, {1, 1, 0}}
The flipped matrix is {{1, 0, 1}, {0, 0, 1}}.
Input: arr[][] = {{0, 1, 0}, {1, 1, 0}}, queries[][] = {{1, 1, 2, 3}, {1, 1, 1, 1], {1, 2, 2, 3}}
Output: [[0, 1, 0], [0, 1, 0]]
Explanation:
Query 1:
Submatrix to be flipped = [[0, 1, 0], [1, 1, 0]]
Flipped submatrix is [[1, 0, 1], [0, 0, 1]].
Therefore, the modified matrix is [[1, 0, 1], [0, 0, 1]].
Query 2:
Submatrix to be flipped = [[1]]
Flipped submatrix is [[0]]
Therefore, matrix is [[0, 0, 1], [0, 0, 1]].
Query 3:
Submatrix to be flipped = [[0, 1], [0, 1]]
Flipped submatrix is [[1, 0], [1, 0]]
Therefore, modified matrix is [[0, 1, 0], [0, 1, 0]].
天真的方法:解决每个查询问题的最简单方法是遍历给定的子矩阵,并针对每个元素检查其是否为0或1,然后进行相应翻转。在完成所有查询的这些操作之后,打印获得的最终矩阵。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to flip a submatrices
void manipulation(vector> &matrix,
vector &q)
{
// Boundaries of the submatrix
int x1 = q[0], y1 = q[1],
x2 = q[2], y2 = q[3];
// Iterate over the submatrix
for(int i = x1 - 1; i < x2; i++)
{
for(int j = y1 - 1; j < y2; j++)
{
// Check for 1 or 0
// and flip accordingly
if (matrix[i][j] == 1)
matrix[i][j] = 0;
else
matrix[i][j] = 1;
}
}
}
// Function to perform the queries
void queries_fxn(vector> &matrix,
vector> &queries)
{
for(auto q : queries)
manipulation(matrix, q);
}
// Driver code
int main()
{
vector> matrix = { { 0, 1, 0 },
{ 1, 1, 0 } };
vector> queries = { { 1, 1, 2, 3 },
{ 1, 1, 1, 1 },
{ 1, 2, 2, 3 } };
// Function call
queries_fxn(matrix, queries);
cout << "[";
for(int i = 0; i < matrix.size(); i++)
{
cout << "[";
for(int j = 0; j < matrix[i].size(); j++)
cout << matrix[i][j] << " ";
if (i == matrix.size() - 1)
cout << "]";
else
cout << "], ";
}
cout << "]";
}
// This code is contributed by bgangwar59
Java
// Java program to implement
// the above approach
import java.util.*;
import java.lang.*;
class GFG{
// Function to flip a submatrices
static void manipulation(int[][] matrix,
int[] q)
{
// Boundaries of the submatrix
int x1 = q[0], y1 = q[1],
x2 = q[2], y2 = q[3];
// Iterate over the submatrix
for(int i = x1 - 1; i < x2; i++)
{
for(int j = y1 - 1; j < y2; j++)
{
// Check for 1 or 0
// and flip accordingly
if (matrix[i][j] == 1)
matrix[i][j] = 0;
else
matrix[i][j] = 1;
}
}
}
// Function to perform the queries
static void queries_fxn(int[][] matrix,
int[][] queries)
{
for(int[] q : queries)
manipulation(matrix, q);
}
// Driver code
public static void main (String[] args)
{
int[][] matrix = {{0, 1, 0}, {1, 1, 0}};
int[][] queries = {{1, 1, 2, 3},
{1, 1, 1, 1},
{1, 2, 2, 3}};
// Function call
queries_fxn(matrix, queries);
System.out.print("[");
for(int i = 0; i < matrix.length; i++)
{
System.out.print("[");
for(int j = 0; j < matrix[i].length; j++)
System.out.print(matrix[i][j] + " ");
if(i == matrix.length - 1)
System.out.print("]");
else
System.out.print("], ");
}
System.out.print("]");
}
}
// This code is contributed by offbeat
Python3
# Python3 Program to implement
# the above approach
# Function to flip a submatrices
def manipulation(matrix, q):
# Boundaries of the submatrix
x1, y1, x2, y2 = q
# Iterate over the submatrix
for i in range(x1-1, x2):
for j in range(y1-1, y2):
# Check for 1 or 0
# and flip accordingly
if matrix[i][j]:
matrix[i][j] = 0
else:
matrix[i][j] = 1
# Function to perform the queries
def queries_fxn(matrix, queries):
for q in queries:
manipulation(matrix, q)
# Driver Code
matrix = [[0, 1, 0], [1, 1, 0]]
queries = [[1, 1, 2, 3], \
[1, 1, 1, 1], \
[1, 2, 2, 3]]
# Function call
queries_fxn(matrix, queries)
print(matrix)
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to flip a submatrices
static void manipulation(int[,] matrix,
int[] q)
{
// Boundaries of the submatrix
int x1 = q[0], y1 = q[1],
x2 = q[2], y2 = q[3];
// Iterate over the submatrix
for(int i = x1 - 1; i < x2; i++)
{
for(int j = y1 - 1; j < y2; j++)
{
// Check for 1 or 0
// and flip accordingly
if (matrix[i, j] == 1)
matrix[i, j] = 0;
else
matrix[i, j] = 1;
}
}
}
public static int[] GetRow(int[,] matrix, int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new int[rowLength];
for(var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
// Function to perform the queries
static void queries_fxn(int[,] matrix,
int[,] queries)
{
for(int i = 0; i < queries.GetLength(0); i++)
manipulation(matrix, GetRow(queries, i));
}
// Driver code
public static void Main(String[] args)
{
int[,] matrix = { { 0, 1, 0 },
{ 1, 1, 0 } };
int[,] queries = { { 1, 1, 2, 3 },
{ 1, 1, 1, 1 },
{ 1, 2, 2, 3 } };
// Function call
queries_fxn(matrix, queries);
Console.Write("[");
for(int i = 0; i < matrix.GetLength(0); i++)
{
Console.Write("[");
for(int j = 0; j < matrix.GetLength(1); j++)
Console.Write(matrix[i, j] + ", ");
if (i == matrix.Length - 1)
Console.Write("]");
else
Console.Write("], ");
}
Console.Write("]");
}
}
// This code is contributed by Princi Singh
Python3
# Python3 program to implement
# the above approach
# Function to modify dp[][] array by
# generating prefix sum
def modifyDP(matrix, dp):
for j in range(1, len(matrix)+1):
for k in range(1, len(matrix[0])+1):
# Update the tabular data
dp[j][k] = dp[j][k] + dp[j-1][k] \
+ dp[j][k-1]-dp[j-1][k-1]
# If the count of flips is even
if dp[j][k] % 2 != 0:
matrix[j-1][k-1] = int(matrix[j-1][k-1]) ^ 1
# Function to update dp[][] matrix
# for each query
def queries_fxn(matrix, queries, dp):
for q in queries:
x1, y1, x2, y2 = q
# Update the table
dp[x1][y1] += 1
dp[x2 + 1][y2 + 1] += 1
dp[x1][y2 + 1] -= 1
dp[x2 + 1][y1] -= 1
modifyDP(matrix, dp)
# Driver Code
matrix = [[0, 1, 0], [1, 1, 0]]
queries = [[1, 1, 2, 3], \
[1, 1, 1, 1], \
[1, 2, 2, 3]]
# Initialize dp table
dp = [[0 for i in range(len(matrix[0])+2)] \
for j in range(len(matrix)+2)]
queries_fxn(matrix, queries, dp)
print(matrix)
[[0, 1, 0], [0, 1, 0]]
时间复杂度: O(N * M * Q)
辅助空间: O(1)
高效方法:可以使用动态编程和Prefix Sum技术优化上述方法。标记每个查询中涉及的子矩阵的边界,然后计算矩阵中涉及的运算的前缀和,并相应地更新矩阵。请按照以下步骤解决问题:
- 初始化2D状态空间表dp [] [],以将翻转的次数存储在矩阵的各个索引处
- 对于每个查询{x1,y1,x2,y2,K},通过以下操作更新dp [] []矩阵:
- dp [x1] [y1] + = 1
- dp [x2 + 1] [y1]-= 1
- dp [x2 +1] [y2 +1] + = 1
- dp [x1] [y2 + 1]-= 1
- 现在,遍历dp [] []矩阵,并通过以下关系计算行和列以及对角线的前缀和,从而更新dp [i] [j]:
dp[i][j] = dp[i][j] + dp[i-1][j] + dp[i][j – 1] – dp[i – 1][j – 1]
- 如果发现dp [i] [j]为奇数,则将mat [i – 1] [j – 1]减1。
- 最后,打印更新后的矩阵mat [] []作为结果。
下面是上述方法的实现:
Python3
# Python3 program to implement
# the above approach
# Function to modify dp[][] array by
# generating prefix sum
def modifyDP(matrix, dp):
for j in range(1, len(matrix)+1):
for k in range(1, len(matrix[0])+1):
# Update the tabular data
dp[j][k] = dp[j][k] + dp[j-1][k] \
+ dp[j][k-1]-dp[j-1][k-1]
# If the count of flips is even
if dp[j][k] % 2 != 0:
matrix[j-1][k-1] = int(matrix[j-1][k-1]) ^ 1
# Function to update dp[][] matrix
# for each query
def queries_fxn(matrix, queries, dp):
for q in queries:
x1, y1, x2, y2 = q
# Update the table
dp[x1][y1] += 1
dp[x2 + 1][y2 + 1] += 1
dp[x1][y2 + 1] -= 1
dp[x2 + 1][y1] -= 1
modifyDP(matrix, dp)
# Driver Code
matrix = [[0, 1, 0], [1, 1, 0]]
queries = [[1, 1, 2, 3], \
[1, 1, 1, 1], \
[1, 2, 2, 3]]
# Initialize dp table
dp = [[0 for i in range(len(matrix[0])+2)] \
for j in range(len(matrix)+2)]
queries_fxn(matrix, queries, dp)
print(matrix)
[[0, 1, 0], [0, 1, 0]]
时间复杂度: O(N * M)
辅助空间: O(N * M)