第十三届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组 统计子矩阵
问题描述
给定一个 N×MN×M 的矩阵 AA, 请你统计有多少个子矩阵 (最小 1×11×1, 最大 N×M)N×M) 满足子矩阵中所有数的和不超过给定的整数 KK ?
输入格式
第一行包含三个整数 N,MN,M 和 KK.
之后 NN 行每行包含 MM 个整数, 代表矩阵 AA.
输出格式
一个整数代表答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[510][510];
int main()
{
int n, m, k;
long long ans = 0;
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];
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
{
//从第i行到第j行,每一列看做一个数字a[j][1:m]-a[i-1][1:m]
//双指针,左端点等于l,右端点等于r,和为sum
for(int l = 1, r = 1, sum = 0; r <= m; r++)
{
sum += a[j][r] - a[i - 1][r];
//如果sum超过k是不合法的,需要右移左边界l,使得sum变小
while(sum > k)
{
sum -= a[j][l] - a[i - 1][l];
l += 1;
}
ans += r - l + 1;
}
}
cout<<ans<<endl;
return 0;
}