差分矩阵问题

差分矩阵

原题再现

输入一个 n 行 m列的整数矩阵,再输入 q个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1)和 (x2,y2)表示一个子矩阵的左上角坐标和右下角坐标。

每个操作都要将选中的子矩阵中的每个元素的值加上 c

请你将进行完所有操作后的矩阵输出。

思路

1维的差分

我们先来看1维的差分

我们要实现一维的数据的差分,就先拿来一个一维数组a,比如长度为m的数组,需要实现下标从c0到c1这个区间都加上c,此时我们可以构建一个差分数组b,使得a数组是b数组的前缀和,那么可得以下公式

a~n~ = b~1~ + b~2~ + b~3~ + ... + b~n~

那么可得将一维数组a从c0到c1加上c就可以认为是在b数组的b~c0~ + c

而b~c1~ - c ,如此可得新的b数组,将b数组求前缀和即可得到a数组从c0到c1这个区间加上c

二维的差分

我们再来看二维的差分

我们要求m x n维矩阵 (x~1~,y~1~) - (x~2~,y~2~)围成矩阵a的所有数 + c,此时我们可以安装一维数组的思路来做题,构建出二维差分数组b,此时a矩阵围成矩阵 + c在b矩阵就表现为

b(x~1~,y~1~) + c

b(x~1~,y~2~ + 1) - c

b(x~2~ + 1,y~1~) - c

b(x~2~ + 1,y~2~ + 1) + c

如此我们可以得到a矩阵的划分矩阵 + c的解决方法,就是按照上述步骤给b矩阵进行操作即可得到最终操作完成后a矩阵的差分矩阵b,再将b矩阵进行前缀和即可得到新的a矩阵,此时a矩阵就是题目所要求的矩阵输出即可。

至于差分矩阵的构建,将a和b矩阵都看作是0矩阵,然后按照以上所给的公式,依次将a矩阵的值当作c,对b矩阵操作即可,最终可得到b矩阵。

参数如下:

1 2 2 1

3 2 2 1

1 1 1 1

1 1 2 2 1

1 3 2 3 2

3 1 3 4 1`

代码如下:

java 复制代码
public class Main{
    public static void main(String[] args){
        try{
         BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            int n = 3;
            int m = 4;
            int q = 3;
            
            int[][] con = new int[3][4];
            int[][] cha = new int[3][4];
            
            for(int i = 1;i <= n;i++){
                String[] b = bf.readLine().split(" ");
                for(int j = 1; j <= m;j++){
                    con[i][j] = Integer.parseInt(b[j - 1]);
                }
            }
            
            for(int i = 1;i <= n;i++){
                for(int j = 1;j <= m;j++){
                    insert(cha,i,j,i,j,con[i][j]);
                }
            }
			while((q--) > 0){
                String[] c = bf.readLine().split(" ");
                int x1 = Integer.parseInt(c[0]);
                 int y1 = Integer.parseInt(c[1]);
                int x2 = Integer.parseInt(c[2]);
                 int y2 = Integer.parseInt(c[3]); 
                 int d = Integer.parseInt(c[4]);
                 
                 insert(cha,x1,y1,x2,y2,d);
            }
            
            for(int i = 1;i <= n;i++){
                for(int j = 1;j <= m;j++){
                    cha[i][j] += cha[i - 1][j] + cha[i][j - 1] - cha[i - 1][j - 1];
                }
            }
            
             for(int i = 1;i <= n;i++){
                for(int j = 1;j <= m;j++){
                    System.out.print(cha[i][j] + " ");
                }
                 System.out.println();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
 public static void insert(int[][] cha,int x1,int y1,int x2,int y2,int c){
        cha[x1][y1] += c;
        cha[x2 + 1][y1] -= c;
        cha[x1][y2 + 1] -= c;
        cha[x2 + 1][y2 + 1] += c;
    }
}
相关推荐
小王C语言31 分钟前
【数据结构初阶】---时间复杂度和空间复杂度了解及几道相关OJ题
java·数据结构·算法
小马爱打代码36 分钟前
设计模式详解(单例模式)
java·单例模式·设计模式
Java中文社群38 分钟前
华为一面:谈谈你对JWT的理解?
java·后端·面试
caihuayuan539 分钟前
Golang的代码注释规范指南
java·大数据·spring boot·后端·课程设计
m0_7482548842 分钟前
【华为OD机考】2024E+D卷真题【完全原创题解 详细考点分类 不断更新题目 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·华为od
~Yogi1 小时前
每日学习Java之一万个为什么?(Maven篇+RPC起步+CICD起步)(待完善)
java·学习·maven
银之夏雪1 小时前
ESLint 深度解析:原理、规则与插件开发实践
java·前端·javascript
重生之成了二本看我逆天改命走向巅峰1 小时前
从0搭建Tomcat第二天:深入理解Servlet容器与反射机制
java·开发语言·笔记·学习·servlet·tomcat·idea
rkmhr_sef1 小时前
Java进阶:Dubbo
java·开发语言·dubbo
不止会JS2 小时前
cursor使用经验分享(java后端服务开发向)
java·开发语言·经验分享·cursor