题目描述
输入一个 n 行 m 列的整数矩阵,再输入 q 个询问,每个询问包含四个整数 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。
对于每个询问输出子矩阵中所有数的和。
样例
3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4
样例答案
17
27
21
算法1
二维前缀和$O(n^2)$
S[i,j]=S[i,j−1]+S[i−1,j]−S[i−1,j−1]+a[i,j]
(x1,y1),(x2,y2)(x1,y1),(x2,y2) 这一子矩阵中的所有数之和为:S[x2,y2]−S[x1−1,y2]−S[x2,y1−1]+S[x1−1,y1−1]
C++ 代码
#include <iostream>
using namespace std;
const int N = 1010;
int a[N][N],s[N][N];
int main()
{
int n,m,q,x1,y1,x2,y2;
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]+a[i][j];
}
}
while(q-->0)
{
cin>>x1>>y1>>x2>>y2;
int r=s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1];
cout<<r<<endl;
}
}
java 代码
import java.util.*;
public class Main{
static int N=1010;
static int[][] a=new int [N][N];
static int[][] s=new int [N][N];
static int n,m,q;
static int x1,y1,x2,y2,r;
public static void main(String[] args){
Scanner scan=new Scanner(System.in);
n=scan.nextInt();
m=scan.nextInt();
q=scan.nextInt();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]=scan.nextInt();
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
}
}
while(q-->0)
{
x1=scan.nextInt();
y1=scan.nextInt();
x2=scan.nextInt();
y2=scan.nextInt();
r=s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
System.out.println(r);
}
}
}