提示:以下是本篇文章正文内容,下面案例可供参考
一、二维矩阵的前缀和应该怎么做?
1.引入一个二维数组
int[][] arr = {
0 0 0 0 0
0 1 7 2 4
0 3 6 2 8
0 2 1 2 3
}
2.二维前缀和矩阵数组
二维矩阵前缀和和一维矩阵大同小异,我们可以定义矩阵前缀,是以右下角元素为主的矩阵的元素和。
我们可以一步一步的推出二维前缀矩阵里面各个位置的值。设置前缀和矩阵为s例如:我们求s[1][1]的值。
注:我们在初始位置多添加了一行、一列,因为原arr数组这些地方是没有值的
图2.1
图2.2
图2.3
图2.4
即求图2.1黄色区域的面积=图2.2蓝色区域的面积+图2.3绿色区域的面积-图2.4紫色区域的面积(注因s[0][0]即图2.4紫色区域的面积被重复计算了)+arr[1][1]。
s[1][1] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + arr[1][1](注:里面的i=1,j=1)
3.推出二维矩阵前缀和的公式计算
由上述式子推出的s[1][1]的值我们可以推广到公式s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + arr[i][j]
3.1 代码如下
int[][] s = new int[n+1][m+1];
for(int i = 1;i <= n;i++ ){
for(int j = 1;j <= m;j++){
s[i][j] = s[i-1][j] + s[i][j-1]-s[i-1][j-1] + arr[i][j];
}
}
二.求子矩阵的和
1.算法思路
我们给定4个参数x1 y1 x2 y2,即求二维数组从arr[x1][y1]到arr[x2][y2]的区间和(图1.1蓝色区域的面积)
图 1.1
c286e9c2c25f4b0ca758851298095b32.png
图1.2
图 1.3
图1.4
图1.5
我们可以用图1.2黄色区域的面积即s[x2][y2]-图1.3绿色区域的面积即s[x1-1][y2]-图1.4白色区域的面积s[x2][y1-1]+图1.5红色区域的面积s[x1-1][y1-1],就可以求出子矩阵的和。(注:跟我们推导二维前缀和数组的过程基本一样,同样是要加上被重复减去的部分即图1.5中的红色区域的面积)
2 子矩阵和公式推导
公式为 result = s[x2][y2]-s[x1-1][y2]-s[x2][y1-1] + s[x1-1][y1-1]
代码如下:
int x1 = nextInt();
int y1 = nextInt();
int x2 = nextInt();
int y2 = nextInt();
pw.println(s[x2][y2]-s[x1-1][y2] - s[x2][y1-1]+s[x1-1][y1-1]);
三、测试数据
1.代码如下(示例):
import java.io.*;
public class 子矩阵的和 {
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static void main(String[] args) throws Exception{
int n = nextInt();
int m = nextInt();
int q = nextInt();
int[][] arr = new int[n+1][m+1];
for (int i = 1; i <= n; i++) {
for(int j = 1;j <= m;j++){
arr[i][j] = nextInt();
}
}
int[][] s = new int[n+1][m+1];
//构建前缀和矩阵
for(int i = 1;i <= n;i++ ){
for(int j = 1;j <= m;j++){
s[i][j] = s[i-1][j] + s[i][j-1]-s[i-1][j-1] + arr[i][j];
}
}
pw.println("------------------------");
pw.println("前缀和矩阵如下:");
for(int i = 1;i <= n;i++ ){
for(int j = 1;j <= m;j++){
pw.print(s[i][j]+" ");
}
pw.println();
}
pw.println("------------------------");
//测试样例
while(q-- > 0){
int x1 = nextInt();
int y1 = nextInt();
int x2 = nextInt();
int y2 = nextInt();
pw.println(s[x2][y2]-s[x1-1][y2] - s[x2][y1-1]+s[x1-1][y1-1]);
}
pw.flush();
}
public static int nextInt()throws Exception{
st.nextToken();
return (int)st.nval;
}
}
2.测试数据
2.1 测试数据如下
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
2.2运行结果如下
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)
img.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)