题目出处
2022蓝桥杯cpp组
【第十三届】【省赛】【B组】
问题描述
给定一个 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≤Aij≤1000;1≤K≤250000000.
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
知识点:
前缀和(70分)+双指针(100分)
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n, m, k, g[505][505];
long long ans;
int main(){
cin>>n>>m>>k;
for(int i = 1; i<=n; ++i)
for(int j = 1; j<=m; ++j){
scanf("%d", &g[i][j]);
g[i][j] += g[i-1][j] + g[i][j-1] - g[i-1][j-1];
}
for(int i = 1; i<=n; ++i)
for(int j = i; j<=n; ++j){
int l = 1, r;
for(r = 1; r<=m; ++r){
while(g[j][r]-g[j][l-1]-g[i-1][r]+g[i-1][l-1]>k){
l++;
}
ans += r-l+1;
}
}
cout<<ans;
return 0;
}