Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++에서 1의 개수가 0의 개수보다 하나 더 많은 최대 부분행렬 영역

<시간/>

이 튜토리얼에서는 0보다 1이 더 많은 최대 부분행렬 영역을 찾는 프로그램에 대해 논의할 것입니다.

이를 위해 0과 1을 포함하는 행렬이 제공됩니다. 우리의 임무는 0보다 1이 더 많이 포함된 최대 면적의 부분행렬을 얻는 것입니다.

예시

#include <bits/stdc++.h>
using namespace std;
#define SIZE 10
//finding length of longest sub-matrix
int lenOfLongSubarr(int arr[],
int n, int& start, int& finish) {
   unordered_map<int, int> um;
   int sum = 0, maxLen = 0;
   for (int i = 0; i < n; i++) {
      sum += arr[i];
      if (sum == 1) {
         start = 0;
         finish = i;
         maxLen = i + 1;
      }
      else if (um.find(sum) == um.end()) um[sum] = i;
      if (um.find(sum - 1) != um.end()) {
         if (maxLen < (i - um[sum - 1])) start = um[sum - 1] + 1;
         finish = i;
         maxLen = i - um[sum - 1];
      }
   }
   return maxLen;
}
//finding the maximum area
void largestSubmatrix(int mat[SIZE][SIZE], int n) {
   int finalLeft, finalRight, finalTop, finalBottom;
   int temp[n], maxArea = 0, len, start, finish;
   for (int left = 0; left < n; left++) {
      memset(temp, 0, sizeof(temp));
      for (int right = left; right < n; right++) {
         for (int i = 0; i < n; ++i)
         temp[i] += mat[i][right] == 0 ? -1 : 1;
         len = lenOfLongSubarr(temp, n, start, finish);
         if ((len != 0) && (maxArea < (finish - start + 1) * (right - left + 1))) {
            finalLeft = left;
            finalRight = right;
            finalTop = start;
            finalBottom = finish;
            maxArea = (finish - start + 1) * (right - left + 1);
         }
      }
   }
   cout << "(Top, Left): (" << finalTop << ", " << finalLeft << ")\n";
   cout << "(Bottom, Right): (" << finalBottom << ", " << finalRight << ")\n";
   cout << "Maximum area: " << maxArea;
}
int main() {
   int mat[SIZE][SIZE] = {
      { 1, 0, 0, 1 },
      { 0, 1, 1, 1 },
      { 1, 0, 0, 0 },
      { 0, 1, 0, 1 }
   };
   int n = 4; largestSubmatrix(mat, n);
   return 0;
}

출력

(Top, Left): (1, 1)
(Bottom, Right): (3, 3)
Maximum area: 9