首先分析一下二维数组的差分。s[x2][y2]-s[x1][y1]=s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]
因为对于二维数组x2y2-x1y1范围内的值需要通过x2y2减去从x1,y2-1的这段存储的前缀和以及减去x2-1,y1这两部分的前缀和,但是还有一个x1-1,y1-1这一段被减去了两次。我们可以通过举例例如:sum (2,2)∼(3,3)=sum 3,3−sum 1,3−sum 3,1+sum 1,1
以及二维数组的前缀和怎么求对于横轴来书和一维数组一样。s[i][j]=s[i-1][j]+a[i][j]
对于纵轴来说s[i][j]=s[i][j]+s[i][j-1];
通过举例可得
sum (3,3)=sum2 ,3+a[3,1]+a[3,2]+a[3,3]
以下是代码实现
package 二维数组前缀和;
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int m=scan.nextInt();
int q=scan.nextInt();
long [][] a=new long[n+1][m+1];
long [][] s=new long[n+1][m+1];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]=scan.nextInt();
s[i][j]=s[i][j-1]+a[i][j];
}
for (int j = 1; j <= m; j++) {
s[i][j] += s[i - 1][j]; // 二维前缀和处理
}
}
for(int i=0;i<q;i++)
{
int x1=scan.nextInt();
int y1=scan.nextInt();
int x2=scan.nextInt();
int y2=scan.nextInt();
System.out.println(caculate(x1,y1,x2,y2,s));
}
//在此输入您的代码...
scan.close();
}
public static long caculate(int x1,int y1,int x2,int y2,long [][] s)
{
if(x1>x2||y1>y2)
{
return 0;
}
return s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
}
}