P8783统计子矩阵
Hungry_STS · · 题解
题目传送门
三十分做法:
三十分做法就是一个暴力,我们可以枚举左上角和右下角,然后累加这个矩阵。
八十分做法:
这道题一眼看上去就是一个二维前缀和,我们可以用一个前缀数组存前缀和,之后我们枚举左上角和右下角用前缀和求出矩阵和,判断是否小于
80分代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[505][505],s[505][505],k,sum=0;
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j],s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int ii=1;ii<=i;ii++)
for(int jj=1;jj<=j;jj++)
if(s[i][j]-s[ii-1][j]-s[i][jj-1]+s[ii-1][jj-1]<=k)
sum++;
cout<<sum;
}
满分做法:
我们可以举一个一维的例子,因为
于是我们就能看出来,这是一个二维尺取。我们可以枚举
AC代码:
#include<bits/stdc++.h>
#define fst ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
long long n,m,a[505][505],s[505][505],k,sum=0;
int main()
{
fst
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j],s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
for(int jj=1,ii=1;ii<=m;ii++)
{
while(s[j][ii]-s[i-1][ii]-s[j][jj-1]+s[i-1][jj-1]>k&&jj<=ii)
{
jj++;
}
sum+=ii-jj+1;
}
cout<<sum;
}