Median of Bitwise XOR of all submatrices starting from the top left corner
Given a 2D matrix mat[][] of size N * M, the task is to find the median of Bitwise XOR of all possible submatrices from the given matrix having topmost left element at (0, 0).
Examples:
Input : M[][] = { { 1, 2 }, { 2, 3 } }
Output: 2.5
Explanation:
Bitwise XOR of submatrix whose topmost left corner is (0, 0) and bottommost right corner is (0, 0) is mat[0][0] = 1.
Bitwise XOR of submatrix whose topmost left corner is (0, 0) and bottommost right corner is (0, 1) is mat[0][0] ^ mat[0][1] = 3.
Bitwise XOR of submatrix whose topmost left corner is (0, 0) and bottommost right corner is (1, 0) is mat[0][0] ^ mat[1][0] = 3.
Bitwise XOR of submatrix whose topmost left corner is (0, 0) and bottommost right corner is (1, 1) is mat[0][0] ^ mat[1][0] ^ mat[0][1] ^ mat[1][1] = 2.
Median of bitwise XOR of all possible submatrix whose topmost left corner is (2 + 3) / 2 = 2.5.Input : M[][] = { { 1, 5, 2 }, { 2, 3, 23 }, { 7, 43, 13 } }
Output: 5
Approach: The problem can be solved using Dynamic programming based on the following recurrence relation
dp[i][j] = dp[i – 1][j – 1] ^ dp[i][j – 1] ^ dp[i – 1][j] ^ mat[i][j]
mat[i][j]: Stores the Bitwise XOR of the submatrix whose topmost left corner is (0, 0) and bottom most right corner is (i, j).
Follow the steps below to solve the problem:
- Initialize an array, say XOR[], to store the Bitwise XOR of all possible submatrices having topmost left corner is (0, 0).
- Initialize a 2D array, say dp[][], where dp[i][j] stores the bitwise XOR of the submatrix whose topmost left corner is (0, 0) and bottom most right corner is (i, j).
- Fill the dp[][] array using tabulation method.
- Store all the elements of dp[][] array into XOR[].
- Finally, print the median of the XOR[] array.
Below is the implementation of the above approach:
C++
// C++ program to implement // the above approach #include <bits/stdc++.h> #include <iostream> using namespace std; // Function to find the median of bitwise XOR // of all the submatrix whose topmost leftmost // corner is (0, 0) double findMedXOR( int mat[][2], int N, int M) { // dp[i][j]: Stores the bitwise XOR of // submatrix having top left corner // at (0, 0) and bottom right corner at (i, j) int dp[N][M]; int med[N * M]; dp[0][0] = mat[0][0]; med[0] = dp[0][0]; // Stores count of submatrix int len = 1; // Base Case for ( int i = 1; i < N; i++) { dp[i][0] = dp[i - 1][0] ^ mat[i][0]; med[len++] = dp[i][0]; } // Base Case for ( int i = 1; i < M; i++) { dp[0][i] = dp[0][i - 1] ^ mat[0][i]; med[len++] = dp[0][i]; } // Fill dp[][] using tabulation for ( int i = 1; i < N; i++) { for ( int j = 1; j < M; j++) { // Fill dp[i][j] dp[i][j] = dp[i - 1][j] ^ dp[i][j - 1] ^ dp[i - 1][j - 1] ^ mat[i][j]; med[len++] = dp[i][j]; } } sort(med, med + len); if (len % 2 == 0) { return (med[(len / 2)] + med[(len / 2) - 1]) / 2.0; } return med[len / 2]; } // Driver Code int main() { int mat[][2] = { { 1, 2 }, { 2, 3 } }; int N = sizeof (mat) / sizeof (mat[0]); int M = 2; cout << findMedXOR(mat, N, M); return 0; } |
Java
// Java program to implement // the above approach import java.util.*; class GFG { // Function to find the median of bitwise XOR // of all the submatrix whose topmost leftmost // corner is (0, 0) static double findMedXOR( int mat[][], int N, int M) { // dp[i][j]: Stores the bitwise XOR of // submatrix having top left corner // at (0, 0) and bottom right corner at (i, j) int dp[][] = new int [N][M]; int med[] = new int [N * M]; dp[ 0 ][ 0 ] = mat[ 0 ][ 0 ]; med[ 0 ] = dp[ 0 ][ 0 ]; // Stores count of submatrix int len = 1 ; // Base Case for ( int i = 1 ; i < N; i++) { dp[i][ 0 ] = dp[i - 1 ][ 0 ] ^ mat[i][ 0 ]; med[len++] = dp[i][ 0 ]; } // Base Case for ( int i = 1 ; i < M; i++) { dp[ 0 ][i] = dp[ 0 ][i - 1 ] ^ mat[ 0 ][i]; med[len++] = dp[ 0 ][i]; } // Fill dp[][] using tabulation for ( int i = 1 ; i < N; i++) { for ( int j = 1 ; j < M; j++) { // Fill dp[i][j] dp[i][j] = dp[i - 1 ][j] ^ dp[i][j - 1 ] ^ dp[i - 1 ][j - 1 ] ^ mat[i][j]; med[len++] = dp[i][j]; } } Arrays.sort(med); if (len % 2 == 0 ) { return (med[(len / 2 )] + med[(len / 2 ) - 1 ]) / 2.0 ; } return med[len / 2 ]; } // Driver code public static void main(String[] args) { int mat[][] = { { 1 , 2 }, { 2 , 3 } }; int N = mat.length; int M = 2 ; System.out.println(findMedXOR(mat, N, M)); } } // This code is contributed by susmitakundugoaldanga |
Python3
# Python program to implement # the above approach # Function to find the median of bitwise XOR # of all the submatrix whose topmost leftmost # corner is (0, 0) def findMedXOR(mat, N, M): # dp[i][j]: Stores the bitwise XOR of # submatrix having top left corner # at (0, 0) and bottom right corner at (i, j) dp = [[ 0 for i in range (M)] for j in range (N)]; med = [ 0 ] * (N * M); dp[ 0 ][ 0 ] = mat[ 0 ][ 0 ]; med[ 0 ] = dp[ 0 ][ 0 ]; # Stores count of submatrix len = 1 ; # Base Case for i in range ( 1 , N): dp[i][ 0 ] = dp[i - 1 ][ 0 ] ^ mat[i][ 0 ]; med[ len ] = dp[i][ 0 ]; len + = 1 ; # Base Case for i in range ( 1 , M): dp[ 0 ][i] = dp[ 0 ][i - 1 ] ^ mat[ 0 ][i]; med[ len ] = dp[ 0 ][i]; len + = 1 # Fill dp using tabulation for i in range ( 1 , N): for j in range ( 1 , M): # Fill dp[i][j] dp[i][j] = dp[i - 1 ][j] ^ dp[i][j - 1 ] ^ dp[i - 1 ][j - 1 ] ^ mat[i][j]; med[ len ] = dp[i][j]; len + = 1 med.sort(); if ( len % 2 = = 0 ): return (med[( len / / 2 )] + med[( len / / 2 ) - 1 ]) / 2.0 ; return med[ len / / 2 ]; # Driver code if __name__ = = '__main__' : mat = [[ 1 , 2 ], [ 2 , 3 ]]; N = len (mat[ 0 ]); M = 2 ; print (findMedXOR(mat, N, M)); # This code is contributed by 29AjayKumar |
C#
// C# program to implement // the above approach using System; class GFG { // Function to find the median of bitwise XOR // of all the submatrix whose topmost leftmost // corner is (0, 0) static double findMedXOR( int [,]mat, int N, int M) { // dp[i,j]: Stores the bitwise XOR of // submatrix having top left corner // at (0, 0) and bottom right corner at (i, j) int [,]dp = new int [N, M]; int []med = new int [N * M]; dp[0, 0] = mat[0, 0]; med[0] = dp[0, 0]; // Stores count of submatrix int len = 1; // Base Case for ( int i = 1; i < N; i++) { dp[i, 0] = dp[i - 1, 0] ^ mat[i, 0]; med[len++] = dp[i, 0]; } // Base Case for ( int i = 1; i < M; i++) { dp[0, i] = dp[0, i - 1] ^ mat[0, i]; med[len++] = dp[0, i]; } // Fill [,]dp using tabulation for ( int i = 1; i < N; i++) { for ( int j = 1; j < M; j++) { // Fill dp[i,j] dp[i, j] = dp[i - 1, j] ^ dp[i, j - 1] ^ dp[i - 1, j - 1] ^ mat[i, j]; med[len++] = dp[i, j]; } } Array.Sort(med); if (len % 2 == 0) { return (med[(len / 2)] + med[(len / 2) - 1]) / 2.0; } return med[len / 2]; } // Driver code public static void Main(String[] args) { int [,]mat = { { 1, 2 }, { 2, 3 } }; int N = mat.GetLength(0); int M = 2; Console.WriteLine(findMedXOR(mat, N, M)); } } // This code is contributed by 29AjayKumar |
Javascript
<script> // Javascript program to implement // the above approach // Function to find the median of bitwise XOR // of all the submatrix whose topmost leftmost // corner is (0, 0) function findMedXOR(mat, N, M) { // dp[i][j]: Stores the bitwise XOR of // submatrix having top left corner // at (0, 0) and bottom right corner at (i, j) let dp = new Array(N); for (let i = 0; i < N; i++) dp[i] = new Array(M); let med = new Array(N * M); dp[0][0] = mat[0][0]; med[0] = dp[0][0]; // Stores count of submatrix let len = 1; // Base Case for (let i = 1; i < N; i++) { dp[i][0] = dp[i - 1][0] ^ mat[i][0]; med[len++] = dp[i][0]; } // Base Case for (let i = 1; i < M; i++) { dp[0][i] = dp[0][i - 1] ^ mat[0][i]; med[len++] = dp[0][i]; } // Fill dp[][] using tabulation for (let i = 1; i < N; i++) { for (let j = 1; j < M; j++) { // Fill dp[i][j] dp[i][j] = dp[i - 1][j] ^ dp[i][j - 1] ^ dp[i - 1][j - 1] ^ mat[i][j]; med[len++] = dp[i][j]; } } med.sort(); if (len % 2 == 0) { return (med[parseInt(len / 2)] + med[parseInt(len / 2) - 1]) / 2.0; } return med[parseInt(len / 2)]; } // Driver Code let mat = [ [ 1, 2 ], [ 2, 3 ] ]; let N = mat.length; let M = 2; document.write(findMedXOR(mat, N, M)); </script> |
2.5
Time Complexity: O(N * M)
Auxiliary Space: O(N * M)
Please Login to comment...