统计子矩阵
-
核心思想:矩阵前缀和 + 双指针
- 用i和j双指针 遍历所有子矩阵的列
- 用s和t双指针 遍历所有子矩阵的行
- 求其子矩阵的和 若>k 将s向下移动 矩阵和必定减小(元素个数减少)
- 直到满足<=k 因为列一定 行数即为方案数 (从t行往上数到s行 共t-s+1个区间[t,t][t-1,t]....[s,t])
cpp
#include<iostream>
using namespace std;
const int N = 510;
typedef long long LL;
int a[N][N];
int n,m,k;
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 res = 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++;
if(s<=t) res += t-s+1;
}
}
}
cout<<res;
}