给定一个 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 个。
————————————————
100%:
#include<stdio.h>
long long a[503][503]={0},s[503][503]={0};
int main()
{
long long n,m,k,i,j,p,q,num=0,sum;
scanf("%lld %lld %lld",&n,&m,&k);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%lld",&a[i][j]);
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
}
}
for(i=1;i<=n;i++){
for(j=i;j<=n;j++){
for(p=1,q=1;q<=m;q++){
sum=s[j][q]-s[j][p-1]-s[i-1][q]+s[i-1][p-1];
while(sum>k){
p++;
sum=s[j][q]-s[j][p-1]-s[i-1][q]+s[i-1][p-1];
}
num+=(q-p+1);
}
}
}
/* for(p=1,q=1;q<=n;q++){
sum=s[q]-s[p-1];
while(sum>k){
p++;
sum=s[q]-s[p-1];
}
num+=q-p+1;
}
*/
printf("%lld",num);
return 0;
}
70%:
#include<stdio.h>
long long a[503][503]={0},s[503][503]={0};
int main()
{
long long n,m,k,i,j,p,q,num=0,sum;
scanf("%lld %lld %lld",&n,&m,&k);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%lld",&a[i][j]);
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
}
}
for(i=1;i<=n;i++){
for(j=i;j<=n;j++){
for(p=1,q=1;p<=m;p++,q=p){
sum=s[j][q]-s[j][p-1]-s[i-1][q]+s[i-1][p-1];
while(sum<=k&&q<=m){
q++;
sum=s[j][q]-s[j][p-1]-s[i-1][q]+s[i-1][p-1];
}
num+=(q-p);
}
}
}
/* for(p=1,q=1;p<=n;p++){
sum=s[q]-s[p-1];
while(sum<=k&&q<=n){
q++;
sum=s[q]-s[p-1];
}
num+=q-p;
}
*/
printf("%lld",num);
return 0;
}