정수 값을 포함하는 행렬이 주어진다고 가정합니다. 행렬 요소의 합이 주어진 목표 합 값과 같은 행렬에서 부분행렬을 찾아야 합니다. 부분행렬의 수를 반환합니다.
따라서 입력이 다음과 같으면
| 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 1 |
target =5이면 출력은 3이 됩니다.
요소의 합이 6인 부분행렬의 수는 2입니다.
이 문제를 해결하기 위해 다음 단계를 따릅니다. −
- n :=매트 크기
- m :=(n이 0과 같으면 0, 그렇지 않으면 mat[0]의 크기)
- m> n이면 -
- m x n 차원의 하나의 2D 배열 전치 정의
- 초기화 i의 경우:=0, i
- j 초기화의 경우:=0, j
- transpose[j, i] :=mat[i, j]
- j 초기화의 경우:=0, j
- (pcnt[pref]를 1씩 증가)
예시
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
#include<bits/stdc++.h>
using namespace std;
int solve(vector<vector<int>>& mat, int sumTarget) {
int n = mat.size();
int m = n == 0 ? 0 : mat[0].size();
if (m > n) {
vector<vector<int>> transpose(m, vector<int>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
transpose[j][i] = mat[i][j];
}
}
return solve(transpose, sumTarget);
}
int ans = 0;
for (int p = 0; p < m; p++) {
vector<int> arr(n);
for (int q = p; q < m; q++) {
for (int i = 0; i < n; i++) {
arr[i] += mat[i][q];
}
unordered_map<int, int> pcnt = {{0, 1}};
int pref = 0;
for (int i = 0; i < n; i++) {
pref += arr[i];
auto tmp = pcnt.find(pref - sumTarget);
if (tmp != end(pcnt)) ans += tmp->second;
pcnt[pref]++;
}
}
}
return ans;
}
int main() {
vector<vector<int>> mat = {{0, 0, 1, 0}, {0, 1, 0, 0}, {0, 1, 0, 1}, {1, 1, 0, 1}};
cout<< solve(mat, 5) <<endl;
return 0;
} 입력
{{0, 0, 1, 0}, {0, 1, 0, 0}, {0, 1, 0, 1}, {1, 1, 0, 1}}, 5 출력
3