分享
计算二维数组前缀和我们需要先了解二位前缀和的计算公式,公式如下:
我们令b[i][j]为a[i][j]的前缀和数组
b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j]
二位前缀和相较于一维前缀和难度增加了很多,下面用一个例题来解释具体的操作,题目如下:
- 城主小明在王国里圈出一块占地K*K的正方形作为自己的城池希望你选出一块合适的位置,使得他的城池土地价值和最大。
- 输入
第一行三个整数N,M,K,表示大陆的宽和长以及占地正方形的边长。
接下来有N行,每行M个整数,表示大陆上每个地块的价值,价值可能为负数。
N>=1,M=1000,1=<K<=min(N,M) - 输出
一行两个整数X,Y表示小明城池左上角的坐标
代码如下:
#include<iostream>
using namespace std;
int n,m,k;
int a[1005][1005],b[1005][1005];
int main() {
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
scanf("%d",&a[i][j]);
//前缀和
//b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j]
//a[i~i+k][j~j+k]=b[i+k][j+k]-b[i+k][j-1]-b[i-1][j+k]+b[i-1][j-1]
b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j];//b[i][j]为数组a内0~i,0~j范围内数的和
}
}
int maxn=-99999999;
int xx,yy;
k--;
for(int i=1; i<=n-k; i++) {
for(int j=1; j<=m-k; j++) {
int sum=b[i+k][j+k]-b[i+k][j-1]-b[i-1][j+k]+b[i-1][j-1];//求a[i~i+k][j~j+k]
if(sum>maxn) {
xx=i,yy=j;
maxn=sum;
}
}
printf("\n");
}
printf("\n");
cout<<xx<<" "<<yy;
}
可以采用如下输入
3 4 1
1 2 3 1
-1 9 0 2
2 0 1 1
可以得到如下结果
2 2