给定一个 N × M 的矩阵 A,请你统计有多少个子矩阵 (最小 1 × 1,最大 N × M) 满足子矩阵中所有数的和不超过给定的整数 K?
输入格式:
第一行包含三个整数 N, M 和 K.
之后 N 行每行包含 M 个整数,代表矩阵 A.
输出格式
一个整数代表答案。
样例输入
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 个。
对于 30% 的数据,N, M ≤ 20. 对于 70% 的数据,N, M ≤ 100.
对于 100% 的数据,1 ≤ N, M ≤ 500; 0 ≤ Ai j ≤ 1000; 1 ≤ K ≤ 250000000.
cpp
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=510;
LL w[N][N];
LL s[N][N];
int main(){
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>w[i][j];
//每一列的前缀和(一维)
s[i][j]=s[i-1][j]+w[i][j];
}
}
LL sum=0,ans=0;
//找j-i+1行,r-l+1列的子矩阵
for(int i=1;i<=n;i++){//上边界
for(int j=i;j<=n;j++){//下边界
sum=0;
for(int l=1,r=1;r<=m;r++){
sum+=s[j][r]-s[i-1][r];
while(l<=r&&sum>k){
sum-=s[j][l]-s[i-1][l];
l++;
}
ans+=r-l+1;
}
}
}
cout<<ans<<endl;
//二维;
// int n,m,k;
// cin>>n>>m>>k;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// cin>>w[i][j];
// s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+w[i][j];
// }
// }
// LL ans=0;
// for(int x1=1;x1<=n;x1++){
// for(int x2=x1;x2<=n;x2++){
// for(int y1=1,y2=1;y2<=m;y2++){
// while(y1<=y2&&s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]>k) y1++;
// ans+=y2-y1+1;
// }
// }
// }
// cout<<ans<<endl;
return 0;
}