二维数组前缀和(认字就能懂系列)
1、先来说一下思路:
2、先算二维数组的第一行的前缀和,以及第一列的前缀和,sum[0][0]还是a[0][0]。
(上一篇文章说了一维数组的前缀和)
3、如果要算sum[1][1]的前缀和,我先画一个图。黄色的部分,加上红色的部分,再减去左上角的重复的那一块,再加上右下角那个就代表sum[1][1]这四个格子的和。
其实黄色部分的和就是sum[1][0],红色的是sum[0][1],这里就是我上面说的第一列和第一行的前缀和。
那么我们很简单的可以得出一个结论了就是 sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]。
我们现在得到了一个前缀和数组了,问题是怎么得到某个区间的和。
我们再看图
我们要是想得到x1,y1到x2,y2的区间和我们就可以拿着前缀和数组进行操作,怎么操作?我们可以让x2,y2这个整个前缀和减去红色的部分,再减去蓝色部分最后加上红色和蓝色的重合部分,我们就得到了要得到的区间和。
公式就是 sum[x2][y2] - sum[x2][y1-1] - sum[x1-1][y2] + sum[x1-1][y1-1]。
思路都基本搞定了,咱们上代码
#include<bits/stdc++.h>
using namespace std;
const int n = 3,m = 4;
int a[n][m]={{1,2,3,4},
{2,5,6,9},
{6,4,2,3}};
int sum[n][m]={0};
void pre_sum()
{
sum[0][0]=a[0][0];
for(int i=1;i<n;i++) sum[i][0]=sum[i-1][0]+a[i][0]; //第一列
for(int i=1;i<m;i++) sum[0][i]=sum[0][i-1]+a[0][i]; //第一行
for(int i=1;i<n;i++)
{
for(int j=1;j<m;j++)
{
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
}
}
}
int get_sum(int x1,int y1,int x2,int y2)
{
if(!x1&&!y1) return sum[x2][y2]; //表示x1,y1都是0
if(!x1) return sum[x2][y2]-sum[x2][y1-1];//代表x1是0
if(!y1) return sum[x2][y2]-sum[x1-1][y2];//代表y1是0
return sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1];
}
我就把主要的函数写出来了,你自己可以调用(你一定可以的)
希望这期可以帮到你