问题描述
给定一个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
AC代码
#include <iostream>
using namespace std;
const int N=510;
int s[N][N]={0};
int main()
{
// 请在此输入您的代码
int n,m,k;
cin>>n>>m>>k;
int val;
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
cin>>val;
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+val;
}
}
long long sum=0;
// i表示矩阵左上角点的横坐标,j表示矩阵右下角点的横坐标,l表示矩阵左上角点的纵坐标,r表示阵右下角点的纵坐标
for(int i=1; i<=n; i++)
for(int j=i; j<=n; j++)
for(int l=1,r=1; r<=m; r++){
while(l<=r && (s[j][r]-s[i-1][r]-s[j][l-1]+s[i-1][l-1])>k)
l++;
// if(l<=r)
sum+=r-l+1;
}
cout<<sum<<endl;
return 0;
}
思路与知识点
前缀和与双指针
前缀知识不懂的可以看: