Максимальный размер квадратной подматрицы - PullRequest
0 голосов
/ 13 октября 2018

У меня есть матрица размера N * M, заполненная нулями и единицами.Для каждого запроса K я должен ответить на квадратную подматрицу максимального размера, в которой минимум (число 1, число 0) = k, где 1 <= K <= 10 ^ 9.Например, рассмотрим матрицу размером 8 * 8: </p>

10000000
01000000
00000000
00000000
00000000
00000000
00000000
00000000



k= 1        answer= 7
k=2         answer= 8
k=0         answer= 6
k=1001      answer= 8

Я понял, что для k = 1 подматрица (1,1) - (7,7) работает для k = 2,Самая большая квадратная подматрица - это сама исходная матрица.Для k = 1 мы должны получить всю квадратную подматрицу 7 * 7.Найдите их минимум (№ 1, № 0), а затем получите минимум всех из них в качестве ответа.

Я не могу сгенерировать все пары квадратных подматриц.Может ли кто-нибудь помочь мне в достижении этого?Кроме того, если есть какой-либо более короткий путь, это будет хорошо, потому что это занимает очень много времени.

1 Ответ

0 голосов
/ 13 октября 2018

Это вопрос для интервью?Эта проблема очень похожа на проблему максимальной суммы подматрицы (https://www.geeksforgeeks.org/maximum-sum-rectangle-in-a-2d-matrix-dp-27/),, решение DP которой вы должны быть в состоянии адаптировать для этого.

РЕДАКТИРОВАТЬ:

Ниже приводится O (n ^ 3) времени O (n ^ 2) памяти. Импортируемый фрагмент, который нужно понять, это то, что область D = вся область - B - C + A

| A B |
| C D |

#include <stdlib.h>
#include <stdio.h>

int **create_dp(int **matrix, int **dp, int row, int col) {
  dp[0][0] = matrix[0][0];
  for (int i = 1; i < row; ++i) 
    dp[i][0] = matrix[i][0] + dp[i - 1][0];
  for (int j = 1; j < col; ++j) 
    dp[0][j] = matrix[0][j] + dp[0][j - 1];
  for (int i = 1; i < row; ++i) 
    for (int j = 1; j < col; ++j) 
      dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + matrix[i][j] - dp[i - 1][j - 1];
}

int min(int x, int y) { 
  if (x > y) return y;
  return x;
}

int max_square_submatrix(int **matrix, int row, int col, int query) {
  // the value dp[i][j] is the sum of all values in matrix up to i, j 
  // i.e. dp[1][1] = matrix[0][0] + matrix[1][0] + matrix[0][1] + matrix[1][1]
  int **dp = malloc(sizeof(int*) * row);
  for (int i = 0; i < row; ++i) dp[i] = malloc(sizeof(int) * col);
  create_dp(matrix, dp, row, col);
  int global_max_size = 0;
  // go through all squares in matrix
  for (int i = 0; i < row; ++i) {
    for (int j = 0; j < col; ++j) {
      // begin creating square matrices
      // this is the largest size a square matrix could have
      int max_size = min(row - i, col - j) - 1;
      for (; max_size >= 0; --max_size) {
        // you need to see above diagram in order to visualize this step
        int num_ones = dp[i + max_size][j + max_size];
        if (i > 0 && j > 0)
          num_ones += -dp[i + max_size][j - 1] - dp[i - 1][j + max_size] + dp[i - 1][j - 1];
        else if (j > 0)
          num_ones += -dp[i + max_size][j - 1]; 
        else if (i > 0)
          num_ones += -dp[i - 1][j + max_size];
        if (num_ones <= query) break;
      }
      if (global_max_size < max_size + 1) global_max_size = max_size + 1; 
    }
  }
  // free dp memory here
  return global_max_size;
}

int main() {
  #define N 8
  #define M 8
  int **matrix = malloc(sizeof(int*) * N);
  for (int i = 0; i < N; ++i) matrix[i] = malloc(sizeof(int) * M);
  for (int i = 0; i < N; ++i) 
    for (int j = 0; j < M; ++j)
      matrix[i][j] = 0;

  matrix[0][0] = matrix[1][1] = 1;

  printf("%d\n", max_square_submatrix(matrix, 8, 8, 1));
  printf("%d\n", max_square_submatrix(matrix, 8, 8, 2));
  printf("%d\n", max_square_submatrix(matrix, 8, 8, 0));
  printf("%d\n", max_square_submatrix(matrix, 8, 8, 1001));
}
...