给定一个大小为N * M的二维矩阵mat[][] ,任务是从给定矩阵中找到所有可能的子矩阵的按位异或的中值,该矩阵的左上角元素位于(0, 0) 处。
例子:
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
方法:该问题可以使用基于以下递推关系的动态规划解决
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).
请按照以下步骤解决问题:
- 初始化一个数组,比如XOR[] ,以存储所有可能的左上角为(0, 0) 的子矩阵的按位异或。
- 初始化一个二维数组,比如 dp[][],其中 dp[i][j] 存储左上角为(0, 0)且最右下角为(i, j)的子矩阵的按位异或。
- 使用制表方法填充dp[][]数组。
- 将dp[][]数组的所有元素存储到XOR[] 中。
- 最后,打印 XOR[] 数组的中位数。
下面是上述方法的实现:
C++
// C++ program to implement
// the above appraoch
#include
#include
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
2.5
时间复杂度: O(N * M)
辅助空间: O(N * M)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live