#### 二维前缀和+双指针
通过
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 510;
int n,m,k;
int a[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];
a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]; // 计算到当前位置的子矩阵元素和
}
}
ll ans =0;
for(int i=1;i<=m;i++){
for(int j=i;j<=m;j++){
for(int s=1,t=1;t<=n;t++){
while(s<=t && a[t][j]-a[s-1][j]-a[t][i-1]+a[s-1][i-1]>k)s++; // 调整下边界,直到子矩阵的元素和不超过k
if(s<=t) ans+= t-s+1; // 如果下边界在上边界之下,累加可能的子矩阵数量
}
}
}
cout << ans << '\n';
}i是左边界,j是右边界
s为上边界,t为下边界
通过
while 循环来实现的,循环会不断地移动下边界 s,直到找到一个和小于或等于 k 的子矩阵为止。
0 回复
0 转发
0 喜欢
2 阅读



