【题目描述】
给定一个 N×M 的矩阵 A,请你统计有多少个子矩阵 (最小 1×1,最大 N×M) 满足子矩阵中所有数的和不超过给定的整数 K?
【输入格式】
第一行包含三个整数 N,M 和 K。
之后 N 行每行包含 M 个整数,代表矩阵 A。
【输出格式】
一个整数代表答案。
【数据范围】
对于 30% 的数据,N,M≤20,
对于 70% 的数据,N,M≤100,
对于 100% 的数据,1≤N,M≤500;0≤Aij≤1000;1≤K≤2.5×10的8次方。
【输入样例】
3 4 10
1 2 3 4
5 6 7 8
9 10 11 12
【输出样例】
19
【样例解释】
满足条件的子矩阵一共有 19,包含:
- 大小为 1×1 的有 10 个。
- 大小为 1×2 的有 3 个。
- 大小为 1×3 的有 2 个。
- 大小为 1×4 的有 1 个。
- 大小为 2×1 的有 3 个。
【代码】
cpp
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 510;
int n, m, K;
int s[N][N];
int main()
{
scanf("%d%d%d", &n, &m, &K);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
{
scanf("%d", &s[i][j]);
s[i][j] += s[i - 1][j];
}
LL res = 0;
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 ++ ;
}
res += r - l + 1;
}
printf("%lld\n", res);
return 0;
}