Open In App

Count of square submatrices with average at least K

Improve
Improve
Like Article
Like
Save
Share
Report

Given a matrix arr[][] of size NxM and an integer K, the task is to find the count of square submatrices in the given matrix with the average of elements greater than or equal to K.

Examples:

Input: K = 4, arr[][] = {{2, 2, 3}, {3, 4, 5}, {4, 5, 5}}
Output: 7
Explanation: 
The following square submatrices have an average greater than or equal to K:

  1. Square submatrices of dimension (1×1), formed by taking the elements at positions {(2, 2)}. The average of the submatrix is equal to 4.
  2. Square submatrices of dimension (1×1), formed by taking the elements at positions {(2, 3)}. The average of the submatrix is equal to 5.
  3. Square submatrices of dimension (1×1), formed by taking the elements at positions {(3, 1)}. The average of the submatrix is equal to 4.
  4. Square submatrices of dimension (1×1), formed by taking the elements at positions {(3, 2)}. The average of the submatrix is equal to 5.
  5. Square submatrices of dimension (1×1), formed by taking the elements at positions {(3, 3)}. The average of the submatrix is equal to 5.
  6. Square submatrices of dimension (2×2), formed by taking the elements at positions {(2, 1), (2, 2), (3, 1), (3, 2)}. The average of the submatrix is equal to (3+4+4+5 = 16)/4 = 4.
  7. Square submatrices of dimension (2×2), formed by taking the elements at positions {(2, 2), (2, 3), (3, 2), (3, 3)}. The average of the submatrix is equal to (4+5+5+5 = 19)/4 = 4.75.

Therefore, there are totals of 7 square submatrices with an average greater than or equals to K.

Input: K = 3, arr[][] = {{1, 1, 1}, {1, 1, 1}}
Output: 0

Naive Approach: The simplest approach is to generate all possible square submatrices and check sum of all the elements of the sub-square is greater than or equals to K multiplied by the size of the submatrix.

Time Complexity: O(N3 * M3
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized using the prefix sum matrix which results in constant time calculation of the sum of a submatrix. Follow the steps below to solve the problem:

  • Initialize a variable, say count as 0 to store the count of submatrices with an average greater than or equal to K.
  • Calculate the prefix sum of the matrix arr[][] and store it in a vector of vectors say pre[][].
  • Traverse over every element of the matrix using the variables i and j and perform the following steps:
    • Initialize two variables, say l as i and r as j.
    • Iterate until l and r are greater than 0 and in each iteration perform the following steps:
      • Calculate the sum of the square submatrix with the bottom right vertex as (i, j) and the top left vertex as (l, r) and store it in a variable, say sum, i.e sum = pre[i][j] – pre[l-1][r] – pre[l][r-1] + pre[l-1][r-1].
        • Now if the value of K*(i-l+1)*(j-r+1) is equal to the sum, then increment the count by 1.
        • Decrement l and r by 1.
  • Finally, after completing the above steps, print the value of the count as the result.

Below is the implementation of the above approach:

c

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
#define MAX 1000
 
// Function to count submatrices with
// average greater than or equals to K
int cntMatrices(vector<vector<int> > arr, int N, int M,
                int K)
{
 
    // Stores count of submatrices
    int cnt = 0;
 
    // Stores the prefix sum of matrix
    vector<vector<int> > pre(N + 1, vector<int>(M + 1, 0));
 
    // Iterate over the range [1, N]
    for (int i = 1; i <= N; i++) {
 
        // Iterate over the range
        // [1, M]
        for (int j = 1; j <= M; j++) {
 
            // Update the prefix sum
            pre[i][j] = arr[i - 1][j - 1] + pre[i - 1][j]
                        + pre[i][j - 1] - pre[i - 1][j - 1];
        }
    }
 
    // Iterate over the range [1, N]
    for (int i = 1; i <= N; i++) {
 
        // Iterate over the range
        // [1, M]
        for (int j = 1; j <= M; j++) {
 
            // Iterate until l and r
            // are greater than 0
            for (int l = i, r = j; l > 0 && r > 0;
                 l--, r--) {
 
                // Update count
                int sum1 = (K * (i - l + 1) * (i - r + 1));
 
                // Stores sum of submatrix
                // with bottom right corner
                // as (i, j) and top left
                // corner as (l, r)
                int sum2 = pre[i][j] - pre[l - 1][r]
                           - pre[l][r - 1]
                           + pre[l - 1][r - 1];
 
                // If sum1 is less than or
                // equal to sum2
                if (sum1 <= sum2)
 
                    // Increment cnt by 1
                    cnt++;
            }
        }
    }
 
    // Return cnt as the answer
    return cnt;
}
 
// Driver Code
int main()
{
    // Given Input
    vector<vector<int> > arr
        = { { 2, 2, 3 }, { 3, 4, 5 }, { 4, 5, 5 } };
    int K = 4;
    int N = arr.size();
    int M = arr[0].size();
 
    // Function Call
    cout << cntMatrices(arr, N, M, K);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG{
     
static int MAX = 1000;
 
// Function to count submatrixes with
// average greater than or equals to K
static int cntMatrices(int[][] arr, int N,
                    int M, int K)
{
     
    // Stores count of submatrices
    int cnt = 0;
 
    // Stores the prefix sum of matrix
    int[][] pre = new int[N + 1][M + 1];
 
    // Iterate over the range [1, N]
    for(int i = 1; i <= N; i++)
    {
         
        // Iterate over the range
        // [1, M]
        for(int j = 1; j <= M; j++)
        {
             
            // Update the prefix sum
            pre[i][j] = arr[i - 1][j - 1] + pre[i - 1][j] +
                            pre[i][j - 1] - pre[i - 1][j - 1];
        }
    }
 
    // Iterate over the range [1, N]
    for(int i = 1; i <= N; i++)
    {
         
        // Iterate over the range
        // [1, M]
        for(int j = 1; j <= M; j++)
        {
             
            // Iterate until l and r
            // are greater than 0
            for(int l = i, r = j;
                    l > 0 && r > 0; l--, r--)
            {
                 
                // Update count
                int sum1 = (K * (i - l + 1) *
                                (i - r + 1));
 
                // Stores sum of submatrix
                // with bottom right corner
                // as (i, j) and top left
                // corner as (l, r)
                int sum2 = pre[i][j] - pre[l - 1][r] -
                       pre[l][r - 1] + pre[l - 1][r - 1];
 
                // If sum1 is less than or
                // equal to sum2
                if (sum1 <= sum2)
 
                    // Increment cnt by 1
                    cnt++;
            }
        }
    }
 
    // Return cnt as the answer
    return cnt;
}
 
// Driver Code
public static void main(String args[])
{
     
    // Given Input
    int[][] arr = { { 2, 2, 3 },
                    { 3, 4, 5 },
                    { 4, 5, 5 } };
    int K = 4;
    int N = arr.length;
    int M = arr[0].length;
 
    // Function Call
    System.out.println( cntMatrices(arr, N, M, K));
}
}
 
// This code is contributed by avijitmondal1998


Python3




# Python3 program for the above approach
# define MAX 1000
 
# Function to count submatrixes with
# average greater than or equals to K
def cntMatrices(arr, N, M, K):
 
    # Stores count of submatrices
    cnt = 0
 
    # Stores the prefix sum of matrix
    pre = [[0 for i in range(M + 1)]
              for i in range(N + 1)]
               
    # Iterate over the range [1, N]
    for i in range(1, N + 1):
         
        # Iterate over the range
        # [1, M]
        for j in range(1, M + 1):
             
            # Update the prefix sum
            pre[i][j] = (arr[i - 1][j - 1] +
                         pre[i - 1][j] +
                         pre[i][j - 1] -
                         pre[i - 1][j - 1])
 
    # Iterate over the range [1, N]
    for i in range(1, N + 1):
         
        # Iterate over the range
        # [1, M]
        for j in range(1, M + 1):
             
            # Iterate until l and r
            # are greater than 0
            l, r = i, j
            while l > 0 and r > 0:
                 
                # Update count
                sum1 = (K * (i - l + 1) * (i - r + 1))
 
                # Stores sum of submatrix
                # with bottom right corner
                # as (i, j) and top left
                # corner as (l, r)
                sum2 = (pre[i][j] -
                        pre[l - 1][r] - pre[l][r - 1] +
                        pre[l - 1][r - 1])
 
                # If sum1 is less than or
                # equal to sum2
                if (sum1 <= sum2):
                     
                    # Increment cnt by 1
                    cnt += 1
                     
                l -= 1
                r -= 1
 
    # Return cnt as the answer
    return cnt
 
# Driver Code
if __name__ == '__main__':
     
    # Given Input
    arr = [ [ 2, 2, 3 ],
            [ 3, 4, 5 ],
            [ 4, 5, 5 ] ]
    K = 4
    N = len(arr)
    M = len(arr[0])
 
    # Function Call
    print(cntMatrices(arr, N, M, K))
 
# This code is contributed by mohit kumar 29


C#




// C# program for the above approach
using System;
class GFG
{
 
  static int MAX = 1000;
 
  // Function to count submatrixes with
  // average greater than or equals to K
  static int cntMatrices(int[,] arr, int N,
                         int M, int K)
  {
 
    // Stores count of submatrices
    int cnt = 0;
 
    // Stores the prefix sum of matrix
    int[,] pre = new int[N + 1, M + 1];
 
    // Iterate over the range [1, N]
    for(int i = 1; i <= N; i++)
    {
 
      // Iterate over the range
      // [1, M]
      for(int j = 1; j <= M; j++)
      {
 
        // Update the prefix sum
        pre[i, j] = arr[i - 1, j - 1] + pre[i - 1, j] +
          pre[i, j - 1] - pre[i - 1, j - 1];
      }
    }
 
    // Iterate over the range [1, N]
    for(int i = 1; i <= N; i++)
    {
 
      // Iterate over the range
      // [1, M]
      for(int j = 1; j <= M; j++)
      {
 
        // Iterate until l and r
        // are greater than 0
        for(int l = i, r = j;
            l > 0 && r > 0; l--, r--)
        {
 
          // Update count
          int sum1 = (K * (i - l + 1) *
                      (i - r + 1));
 
          // Stores sum of submatrix
          // with bottom right corner
          // as (i, j) and top left
          // corner as (l, r)
          int sum2 = pre[i, j] - pre[l - 1, r] -
            pre[l, r - 1] + pre[l - 1, r - 1];
 
          // If sum1 is less than or
          // equal to sum2
          if (sum1 <= sum2)
 
            // Increment cnt by 1
            cnt++;
        }
      }
    }
 
    // Return cnt as the answer
    return cnt;
  }
 
  // Driver code
  public static void Main(string[] args)
  {
 
    // Given Input
    int[,] arr = { { 2, 2, 3 },
                  { 3, 4, 5 },
                  { 4, 5, 5 } };
    int K = 4;
    int N = arr.GetLength(0);
    int M = arr.GetLength(0);
 
    // Function Call
    Console.WriteLine( cntMatrices(arr, N, M, K));
  }
}
 
// This code is contributed by sanjoy_62.


Javascript




<script>
// Javascript program for the above approach
let MAX = 1000
 
// Function to count submatrixes with
// average greater than or equals to K
function cntMatrices(arr, N, M, K) {
 
    // Stores count of submatrices
    let cnt = 0;
 
    // Stores the prefix sum of matrix
 
    let pre = new Array(N + 1).fill(0).map(() => new Array(M + 1).fill(0))
 
    // Iterate over the range [1, N]
    for (let i = 1; i <= N; i++) {
 
        // Iterate over the range
        // [1, M]
        for (let j = 1; j <= M; j++) {
 
            // Update the prefix sum
            pre[i][j] = arr[i - 1][j - 1] + pre[i - 1][j]
                + pre[i][j - 1] - pre[i - 1][j - 1];
        }
    }
 
    // Iterate over the range [1, N]
    for (let i = 1; i <= N; i++) {
 
        // Iterate over the range
        // [1, M]
        for (let j = 1; j <= M; j++) {
 
            // Iterate until l and r
            // are greater than 0
            for (let l = i, r = j; l > 0 && r > 0;
                l--, r--) {
 
                // Update count
                let sum1 = (K * (i - l + 1) * (i - r + 1));
 
                // Stores sum of submatrix
                // with bottom right corner
                // as (i, j) and top left
                // corner as (l, r)
                let sum2 = pre[i][j] - pre[l - 1][r]
                    - pre[l][r - 1]
                    + pre[l - 1][r - 1];
 
                // If sum1 is less than or
                // equal to sum2
                if (sum1 <= sum2)
 
                    // Increment cnt by 1
                    cnt++;
            }
        }
    }
 
    // Return cnt as the answer
    return cnt;
}
 
// Driver Code
 
// Given Input
let arr = [[2, 2, 3], [3, 4, 5], [4, 5, 5]];
let K = 4;
let N = arr.length;
let M = arr[0].length;
 
// Function Call
document.write(cntMatrices(arr, N, M, K));
 
// This code is contributed by _saurabh_jaiswal.
</script>


Output

7

Time Complexity: O(M * N * (min(N, M))
Auxiliary Space: O(M * N)

 



Last Updated : 01 Dec, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads