Given a Binary Matrix of size N X M, the task is to answer Q queries of the following type;
Query(a, b): Find the number of sub matrices of size a X a with each of its element consisting of the Binary Number b.
We basically need to find submatrices of given sizes with all 1s or all 0s.
Examples:
Input : N = 5, M = 4 m[][] = { { 0, 0, 1, 1 }, { 0, 0, 1, 0 }, { 0, 1, 1, 1 }, { 1, 1, 1, 1 }, { 0, 1, 1, 1 } } Q = 2 Query 1 : a = 2, b = 1 Query 2 : a = 2, b = 0 Output : 4 1 Explanation: For Query 1, 0011 0011 0011 0011 0010 0010 0010 0010 0111 0111 0111 0111 1111 1111 1111 1111 0111 0111 0111 0111 For Query 2, 0011 0010 0111 1111 0111 Input : N = 5, M = 4 m[][] = { { 0, 0, 1, 1 }, { 0, 0, 1, 0 }, { 0, 1, 1, 1 }, { 1, 1, 1, 1 }, { 0, 1, 1, 1 } } Q = 1 Query 1 : a = 3, b = 1 Output : 1
The idea is to use Dynamic Programming to solve the problem. First declare a 2D array dp[][], where value at dp[i][j] (say K) indicates the size of the largest square sub-matrix (K X K) that can be formed whose all elements are equal to m[i][j] and (i, j) is the last element (south-east) of the sub matrix.
Now, dp[i][j] can be defined as:
- If i = 0 OR j = 0 In this Case, dp[i][j] = 1, because only 1 X 1 is the only square matrix that can be formed at 0th row or 0th column whose all elements are equal to m[i][j] and the last element is (i, 0) or (0, j).
- If m[i][j] = m[i-1][j] = m[i][j-1] = m[i-1][j-1] dp[i][j] = min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + 1, if the binary number at m[i][j] is equal to the binary number at m[i-1][j], m[i-1][j-1] and m[i][j-1]. Because if the current binary number is equal to all the three binary numbers it will form a 2 X 2 square sub-matrix where all the elements are equal. Also, it will contribute 1 more row and column to the square matrix with all equal element at position m[i-1][j], m[i-1][j-1] and m[i][j-1].
dp[i][j] = 1, if above conditions do not meet because a single cell will always contribute a 1 X 1 sub matrix.
Now, traverse the 2D dp[][] array and calculate the frequency (freq0[] for the element 0, freq1[] for the element 1) of all the distinct values i.e distinct sizes of square sub-matrix for both 0s and 1s.
Observe, that to count the square sub-matrix of size Y X Y, then Y+1 X Y+1 will also contribute 1 count. Suppose we need to count 2 X 2 matrix and dp[][]=
...22 ...23
Here, the frequency of two is 3 but observe element where dp[i][j] = 3 is also contributing a 2 X 2 square sub-matrix.
So, find the cumulative sum of the frequency for both freq0[] and freq1[].
Below is the implementation of this approach:
// CPP Program to answer queries on number of // submatrix of given size #include <bits/stdc++.h> using namespace std;
#define MAX 100 #define N 5 #define M 4 // Return the minimum of three numbers int min( int a, int b, int c)
{ return min(a, min(b, c));
} // Solve each query on matrix void solveQuery( int n, int m, int mat[N][M], int q,
int a[], int binary[])
{ int dp[n][m], max = 1;
// For each of the cell.
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
// finding submatrix size of both row
// and column.
if (i == 0 || j == 0)
dp[i][j] = 1;
// intermediate cells.
else if ((mat[i][j] == mat[i - 1][j]) &&
(mat[i][j] == mat[i][j - 1]) &&
(mat[i][j] == mat[i - 1][j - 1])) {
dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1],
dp[i][j - 1])
+ 1;
if (max < dp[i][j])
max = dp[i][j];
}
else
dp[i][j] = 1;
}
}
int freq0[MAX] = { 0 }, freq1[MAX] = { 0 };
// Find frequency of each distinct size
// for 0s and 1s.
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
if (mat[i][j] == 0)
freq0[dp[i][j]]++;
else
freq1[dp[i][j]]++;
}
}
// Find the Cumulative Sum.
for ( int i = max - 1; i >= 0; i--) {
freq0[i] += freq0[i + 1];
freq1[i] += freq1[i + 1];
}
// Output the answer for each query
for ( int i = 0; i < q; i++) {
if (binary[i] == 0)
cout << freq0[a[i]] << endl;
else
cout << freq1[a[i]] << endl;
}
} // Driver Program int main()
{ int n = 5, m = 4;
int mat[N][M] = {
{ 0, 0, 1, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 1, 1 }
};
int q = 2;
int a[] = { 2, 2 };
int binary[] = { 1, 0 };
solveQuery(n, m, mat, q, a, binary);
return 0;
} |
// Java Program to answer queries on number of // submatrix of given size import java.io.*;
class GFG {
static int MAX = 100 ;
static int N = 5 ;
static int M = 4 ;
// Return the minimum of three numbers
static int min( int a, int b, int c)
{
return Math.min(a, Math.min(b, c));
}
// Solve each query on matrix
static void solveQuery( int n, int m, int mat[][],
int q, int a[], int binary[])
{
int dp[][] = new int [n][m];
int max = 1 ;
// For each of the cell.
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < m; j++) {
// finding submatrix size of both row
// and column.
if (i == 0 || j == 0 )
dp[i][j] = 1 ;
// intermediate cells.
else if ((mat[i][j] == mat[i - 1 ][j])
&& (mat[i][j] == mat[i][j - 1 ])
&& (mat[i][j] == mat[i - 1 ][j - 1 ]))
{
dp[i][j] = min(dp[i - 1 ][j],
dp[i - 1 ][j - 1 ],
dp[i][j - 1 ]) + 1 ;
if (max < dp[i][j])
max = dp[i][j];
}
else
dp[i][j] = 1 ;
}
}
int freq0[] = new int [MAX];
int freq1[] = new int [MAX];
// Find frequency of each distinct size
// for 0s and 1s.
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < m; j++) {
if (mat[i][j] == 0 )
freq0[dp[i][j]]++;
else
freq1[dp[i][j]]++;
}
}
// Find the Cumulative Sum.
for ( int i = max - 1 ; i >= 0 ; i--) {
freq0[i] += freq0[i + 1 ];
freq1[i] += freq1[i + 1 ];
}
// Output the answer for each query
for ( int i = 0 ; i < q; i++) {
if (binary[i] == 0 )
System.out.println( freq0[a[i]]);
else
System.out.println( freq1[a[i]]);
}
}
// Driver Program
public static void main (String[] args)
{
int n = 5 , m = 4 ;
int mat[][] = { { 0 , 0 , 1 , 1 },
{ 0 , 0 , 1 , 0 },
{ 0 , 1 , 1 , 1 },
{ 1 , 1 , 1 , 1 },
{ 0 , 1 , 1 , 1 } };
int q = 2 ;
int a[] = { 2 , 2 };
int binary[] = { 1 , 0 };
solveQuery(n, m, mat, q, a, binary);
}
} // This code is contributed by anuj_67. |
# Python 3 Program to answer queries on number of # submatrix of given size MAX = 100
N = 5
M = 4
# Solve each query on matrix def solveQuery(n, m, mat, q,
a, binary):
dp = [[ 0 for x in range (m)] for y in range (n)]
max = 1
# For each of the cell.
for i in range (n):
for j in range (m):
# finding submatrix size of both row
# and column.
if (i = = 0 or j = = 0 ):
dp[i][j] = 1
# intermediate cells.
elif ((mat[i][j] = = mat[i - 1 ][j]) and
(mat[i][j] = = mat[i][j - 1 ]) and
(mat[i][j] = = mat[i - 1 ][j - 1 ])):
dp[i][j] = ( min (dp[i - 1 ][j], min (dp[i - 1 ][j - 1 ],
dp[i][j - 1 ])) + 1 )
if ( max < dp[i][j]):
max = dp[i][j]
else :
dp[i][j] = 1
freq0 = [ 0 ] * MAX
freq1 = [ 0 ] * MAX
# Find frequency of each distinct size
# for 0s and 1s.
for i in range (n):
for j in range (m):
if (mat[i][j] = = 0 ):
freq0[dp[i][j]] + = 1
else :
freq1[dp[i][j]] + = 1
# Find the Cumulative Sum.
for i in range ( max - 1 , - 1 , - 1 ):
freq0[i] + = freq0[i + 1 ]
freq1[i] + = freq1[i + 1 ]
# Output the answer for each query
for i in range (q):
if (binary[i] = = 0 ):
print (freq0[a[i]])
else :
print (freq1[a[i]])
# Driver Program if __name__ = = "__main__" :
n = 5
m = 4
mat = [
[ 0 , 0 , 1 , 1 ],
[ 0 , 0 , 1 , 0 ],
[ 0 , 1 , 1 , 1 ],
[ 1 , 1 , 1 , 1 ],
[ 0 , 1 , 1 , 1 ]
]
q = 2
a = [ 2 , 2 ]
binary = [ 1 , 0 ]
solveQuery(n, m, mat, q, a, binary)
# This code is contributed by ukasp.
|
// C# Program to answer // queries on number of // submatrix of given size using System;
class GFG
{ static int MAX = 100;
// static int N = 5;
// static int M = 4;
// Return the minimum
// of three numbers
static int min( int a,
int b,
int c)
{
return Math.Min(a, Math.Min(b, c));
}
// Solve each query on matrix
static void solveQuery( int n, int m,
int [,]mat, int q,
int []a, int []binary)
{
int [,]dp = new int [n, m];
int max = 1;
// For each of the cell.
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < m; j++)
{
// finding submatrix size
// of both row and column.
if (i == 0 || j == 0)
dp[i, j] = 1;
// intermediate cells.
else if ((mat[i, j] == mat[i - 1, j]) &&
(mat[i, j] == mat[i, j - 1]) &&
(mat[i, j] == mat[i - 1, j - 1]))
{
dp[i, j] = min(dp[i - 1, j],
dp[i - 1, j - 1],
dp[i, j - 1]) + 1;
if (max < dp[i, j])
max = dp[i, j];
}
else
dp[i, j] = 1;
}
}
int []freq0 = new int [MAX];
int []freq1 = new int [MAX];
// Find frequency of each
// distinct size for 0s and 1s.
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < m; j++)
{
if (mat[i, j] == 0)
freq0[dp[i, j]]++;
else
freq1[dp[i, j]]++;
}
}
// Find the Cumulative Sum.
for ( int i = max - 1; i >= 0; i--)
{
freq0[i] += freq0[i + 1];
freq1[i] += freq1[i + 1];
}
// Output the answer
// for each query
for ( int i = 0; i < q; i++)
{
if (binary[i] == 0)
Console.WriteLine(freq0[a[i]]);
else
Console.WriteLine(freq1[a[i]]);
}
}
// Driver Code
public static void Main ()
{
int n = 5, m = 4;
int [,]mat = {{0, 0, 1, 1},
{0, 0, 1, 0},
{0, 1, 1, 1},
{1, 1, 1, 1},
{0, 1, 1, 1}};
int q = 2;
int []a = {2, 2};
int []binary = {1, 0};
solveQuery(n, m, mat,
q, a, binary);
}
} // This code is contributed by anuj_67. |
<script> // Javascript Program to answer queries on number of // submatrix of given size var MAX = 100
var N = 5
var M = 4
// Return the minimum of three numbers function min(a, b, c)
{ return Math.min(a, Math.min(b, c));
} // Solve each query on matrix function solveQuery(n, m, mat, q, a, binary)
{ var dp = Array.from(Array(n),()=>Array(m));
var max = 1;
// For each of the cell.
for ( var i = 0; i < n; i++) {
for ( var j = 0; j < m; j++) {
// finding submatrix size of both row
// and column.
if (i == 0 || j == 0)
dp[i][j] = 1;
// intermediate cells.
else if ((mat[i][j] == mat[i - 1][j]) &&
(mat[i][j] == mat[i][j - 1]) &&
(mat[i][j] == mat[i - 1][j - 1])) {
dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1],
dp[i][j - 1])
+ 1;
if (max < dp[i][j])
max = dp[i][j];
}
else
dp[i][j] = 1;
}
}
var freq0 = Array(MAX).fill(0);
var freq1 = Array(MAX).fill(0);
// Find frequency of each distinct size
// for 0s and 1s.
for ( var i = 0; i < n; i++) {
for ( var j = 0; j < m; j++) {
if (mat[i][j] == 0)
freq0[dp[i][j]]++;
else
freq1[dp[i][j]]++;
}
}
// Find the Cumulative Sum.
for ( var i = max - 1; i >= 0; i--) {
freq0[i] += freq0[i + 1];
freq1[i] += freq1[i + 1];
}
// Output the answer for each query
for ( var i = 0; i < q; i++) {
if (binary[i] == 0)
document.write( freq0[a[i]] + "<br>" );
else
document.write( freq1[a[i]] + "<br>" ) ;
}
} // Driver Program var n = 5, m = 4;
var mat = [
[ 0, 0, 1, 1 ],
[ 0, 0, 1, 0 ],
[ 0, 1, 1, 1 ],
[ 1, 1, 1, 1 ],
[ 0, 1, 1, 1 ]
]; var q = 2;
var a = [ 2, 2 ];
var binary = [ 1, 0 ];
solveQuery(n, m, mat, q, a, binary); </script> |
4 1
Time Complexity: O(n * m), where n and m are the numbers of rows and columns respectively.
Auxiliary Space: O(n * m + MAX)