Question description
Given an N × M matrix A, please count how many sub-matrices (minimum 1 × 1, maximum N × M) are there such that the sum of all numbers in the sub-matrix does not exceed the given integer K?
analyze
If you do not consider range issues, etc., you can use the two-digit prefix sum and list it step by step.
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n, m, k, ans, a[N][N], s[N][N];
int main()
{
cin >> n >> m >> k;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
}
}
ans = 0;
for(int x1 = 1; x1 <= n; x1 ++)
{
for(int y1 = 1; y1 <= m; y1 ++)
{
for(int x2 = x1; x2 <= n; x2 ++)
{
for(int y2 = y1; y2 <= m; y2 ++)
{
if (s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1] <= k)ans ++;
}
}
}
}
cout << ans;
return 0;
}
But the quadruple loop will cause the time to exceed the limit
Therefore, optimization can be considered
Loop the upper and lower boundaries and use double pointers to list the left and right boundaries. Since the range must be <= k, if it exceeds this, move the pointer.
Enumerating up and down can be regarded as a one-dimensional problem. Each column can be regarded as an element, which is equivalent to a one-dimensional array. Find which intervals <= k in this array
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n, m, k, sum, ans, a[N][N], s[N][N];
int main()
{
cin >> n >> m >> k;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
s[i][j] = s[i - 1][j] + a[i][j];//算出这一列的前缀和
}
}
for(int i = 1; i <= n; i ++)//枚举上边界
{
for(int j = i; j <= n; j ++)//枚举下边界
{
for(int l = 1, r = 1, sum = 0; r <= m; r ++)//枚举左右边界
{
sum += s[j][r] - s[i - 1][r];
while(sum > k)
{
sum -= s[j][l] - s[i - 1][l];
l ++;
}
ans += r - l + 1;
}
}
}
cout << ans;
return 0;
}