C++ 中給定大小的二進位制子矩陣數量查詢


在這個問題中,我們給定一個大小為 nXm 的二進位制矩陣 bin[][]。我們的任務是解決所有 q 個查詢。對於查詢(x, y),我們需要找到大小為 x*x 的子矩陣的數量,使得陣列 y(二進位制數)的所有元素都滿足條件。

問題描述

這裡,我們需要計算給定大小的子矩陣的總數,這些子矩陣僅包含兩個位元中的一個,即子矩陣的所有元素都是 0/1。

讓我們舉個例子來理解這個問題,

輸入

n = 3 , m = 4
bin[][] = {{ 1, 1, 0, 1}
{ 1, 1, 1, 0}
{ 0, 1, 1, 1}}
q = 1
q1 = (2, 1)

輸出

2

解釋

所有元素都為 1 的大小為 2 的子矩陣為 -

{{ 1, 1, 0, 1}
{ 1, 1, 1, 0}
{ 0, 1, 1, 1}}
{{ 1, 1, 0, 1}
{ 1, 1, 1, 0}
{ 0, 1, 1, 1}}

這個問題的解決方案是使用**動態規劃**方法。為了解決這個問題,我們將維護一個二維矩陣 DP[][] 來儲存相同位元的最大子矩陣。即 DP[i][j] 將儲存以 (i, j) 為結束索引的子矩陣的值,並且所有元素都相同。

為了方便理解,如果 DP[4][5] = 2,則 bin[3][4]、bin[3][5]、bin[4][4] 和 bin[4][5] 中的元素相同。

因此,為了找到 DP[i][j],我們有兩個情況 -

**情況 1** - 如果 i = 0 或 j = 0:DP[i][j] = 1,因為只有一個子矩陣是可能的。

**情況 2** - 否則,bin[i-(k-1)][j] = bin[i][j - (k-1)] …:在這種情況下,DP[i][j] = min(DP[i][j-1],DP[i -1][j],DP[i-1][j-1] ) + 1。這將有助於我們所需的子矩陣。讓我們概括一下 k = 2 的情況,即如果我們考慮一個大小為 2X2 的子矩陣。然後我們需要檢查是否 bin[i][j] = bin[i] [j - 1] = bin[i- 1][j] = bin[i -1 ][j -1],如果可能,我們將找到 k =2 的 DP[i][j]。

如果不滿足情況 2 的條件,我們將設定 DP[i][j] = 1,這可以被視為預設值。

DP[i][j] 的這個值可以用於設定位元或未設定位元。我們將檢查 bin[i][j] 的值以檢視 k 值屬於設定或未設定值中的哪一個。為了找到頻率,我們將建立兩個陣列,zeroFrequrency 用於儲存為 0 生成的子矩陣的頻率。而 oneFrequrency 用於儲存為 1 生成的子矩陣的頻率。

程式說明了解決方案的工作原理,

示例

即時演示

#include <iostream>
using namespace std;
#define N 3
#define M 4

int min(int a, int b, int c) {
   if (a <= b && a <= c)
   return a;
   else if (b <= a && b <= c)
   return b;
   else
   return c;
}

int solveQuery(int n, int m, int bin[N][M], int x, int y){
   int DP[n][m], max = 1;
   for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
         if (i == 0 || j == 0)
         DP[i][j] = 1;
         else if ((bin[i][j] == bin[i - 1][j]) && (bin[i][j] == bin[i][j - 1]) && (bin[i][j] == bin[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 zeroFrequency[n+m] = { 0 }, oneFrequency[n+m] = { 0 };
   for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
         if (bin[i][j] == 0)
         zeroFrequency[DP[i][j]]++;
         else
         oneFrequency[DP[i][j]]++;
      }
   }
   for (int i = max - 1; i >= 0; i--) {
      zeroFrequency[i] += zeroFrequency[i + 1];
      oneFrequency[i] += oneFrequency[i + 1];
   }
   if (y == 0)
   return zeroFrequency[x];
   else
   return oneFrequency[x];
}
int main(){
   int n = 3, m = 4;
   int mat[N][M] =
   {{ 1, 1, 0, 1},
   { 1, 1, 1, 0},
   { 0, 1, 1, 1}};
   int Q = 2;
   int query[Q][2] = {{ 2, 1}, { 1, 0}};
   for(int i = 0; i < Q; i++){
      cout<<"For Query "<<(i+1)<<": The number of Binary sub-matrices of Given size is "            <<solveQuery(n, m, mat, query[i][0], query[i][1])<<"\n";
   }
   return 0;
}

輸出

For Query 1: The number of Binary sub-matrices of Given size is 2
For Query 2: The number of Binary sub-matrices of Given size is 3

更新於:2020-09-09

89 次瀏覽

開啟您的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.