Count sub-matrices having sum divisible 'k' in C++

C++Server Side ProgrammingProgramming

Given a row x col matrix as input. The goal is to find all submatrices within the matrix[row][col] such that the sum of elements of that submatrix is divisible by integer k.

If the matrix is mat[3][3] and k is 4 then submatrices will be as shown below:- 

Let us understand with examples.

For Example

Input - matrix[3][3] = { {1,1,1}, {2,2,2}, {3,3,3} }    k=4

Output - Count of sub-matrices having sum divisible 'k' are: 4

Explanation -  The submatrices will be as shown in above.

Input - matrix[3][3] = { {1,1,1}, {2,2,2 }, {3,3,3} }    k=12

Output - Count of sub-matrices having sum divisible 'k' are: 4

Explanation - The submatrices will be as shown below:-

Approach used in the below program is as follows

In this approach we will traverse the matrix from left to right and for each pair of left and right columns, add elements of the submatrix to array arr[] and separately calculate sum of its elements and subarrays having sum divisible by k.

Function check_val() takes an array having elements of the submatrix as 1D array. Now calculate cumulative sums and check remainders with k and store frequency of remainders in array arr_2[]. 

  • Take matrix[row][col] and integer k as input.
  • Function check_val(int arr[], int size, int k) takes arr[] of elements of submatrices and returns count of all subarrays within arr that have sum divisible by k
  • Take variables count and temp as 0.
  • Take array arr_2[] for storing frequencies of remainders of cumulative sums with k.
  • Calculate cumulative sums using for loop from i=0 to i<size. Add each arr[i] to temp and increment frequency of remainder using arr_2[((temp % k) + k) % k]++ ( for negative sum take mod twice ).
  • Again using for loop traverse frequency array arr_2[] and for each value>1 add arr_2[i] * (arr_2[i] - 1)) / 2 to count as count of all subarrays possible.
  • At the end add arr_2[0] to count.
  • Function matrix_divisible(int matrix[row][col], int size, int k) takes an input submatrix and returns the count of all submatrices having sum divisible by k.
  • Take the initial count as 0.
  • Take a temporary array arr[size].
  • Using two for loops set left column index i and right column index j.
  • Calculate sum of elements as arr[temp]+= matrix[temp][j].
  • For the number of subarrays in arr[] add check_val(arr, size, k) to count.
  • At the end of all for loops, return count as result.

Example

Live Demo

#include <bits/stdc++.h>
using namespace std;
#define row 10
#define col 10

int check_val(int arr[], int size, int k) {
   int count = 0;
   int temp = 0;
   int arr_2[k];
   memset(arr_2, 0, sizeof(arr_2));

   for (int i = 0; i < size; i++) {
      temp = temp + arr[i];
      arr_2[((temp % k) + k) % k]++;
   }
   for (int i = 0; i < k; i++) {
      if (arr_2[i] > 1) {
         count += (arr_2[i] * (arr_2[i] - 1)) / 2;
      }
   }
   count = count + arr_2[0];
   return count;
}

int matrix_divisible(int matrix[row][col], int size, int k) {
   int count = 0;
   int arr[size];

   for (int i = 0; i < size; i++) {
      memset(arr, 0, sizeof(arr));
      for (int j = i; j < size; j++) {
         for (int temp = 0; temp < size; ++temp) {
            arr[temp] += matrix[temp][j];
         }
         count = count + check_val(arr, size, k);
      }
   }
   return count;
}
int main() {
   int matrix[row][col] = {{2,4,-1},{6,1,-9},{2,2, 1}};
   int size = 3, k = 4;
   cout << "Count of sub-matrices having sum divisible ‘k’ are: " << matrix_divisible(matrix, size, k);
   return 0;
}

If we run the above code it will generate the following output

Output

Count of sub-matrices having sum divisible 'k' are: 7

raja
Published on 29-Jan-2021 08:08:48
Advertisements