题目链接:

代码思路:
①枚举上、下边界。
②求每一列前缀和。
②固定上下边界后,在通过双指针确定子矩阵的左右边界。双指针维护一个窗口 [l, r],确保窗口中所有列的和(下面前缀和-上面前缀和)不超过 K。通过滑动窗口方式,计算出以r为右端点的所有子矩阵的有效数量,也就是 子矩阵数量=r - l + 1;
代码如下:
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 550;
int n, m, k;
int g[N][N];
//前缀和 竖
int s[N][N];
//答案
int ans;
signed main(){
//读入
cin >> n >> m >> k;
for(int i = 1; i<= n; i++){
for(int j = 1; j <= m; j++){
cin >> g[i][j];
//计算前缀和
s[i][j] = s[i-1][j] + g[i][j];
}
}
//枚举 上 下 边界
for(int i = 1; i <= n; i++){
for(int j = i; j <= n; j++){
//定义双指针
int l = 1, sum = 0;
for(int r = 1; r <= m; r++){
//加上 r 这一列
sum += s[j][r] - s[i-1][r];
//当sum>k
while(sum > k){
//减去l那一列
sum -= s[j][l] - s[i-1][l];
l++;
}
//加上这个区间所有符合的矩阵数
ans += r-l+1;
}
}
}
cout << ans << endl;
return 0;
}