给定一个 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≤250000000。
输入样例:
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 个。
-
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=510; int w[N][N]; int n,m,k; 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",&w[i][j]); w[i][j]+=w[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+=(w[j][r]-w[i-1][r]); while(sum>k) { sum-=(w[j][l]-w[i-1][l]); l++; } res+=(r-l+1);//以i行为上边界j行为下边界 r为右边界的合法数量 } printf("%lld",res); }