我们考虑一个$N\times M$的矩阵数据,若要对矩阵中的部分数据进行读取,比如求某个$a\times b$的子矩阵的元素和,通常我们可以想到$O(ab)$的遍历那个子矩阵,对它的各个元素进行求和。然而当$a$或$b$很大的时候,这样的计算显得太慢,如果要求子矩阵的最大元素和(如Ural 1146),更是简直慢到不能忍。

        于是就想,能不能在读入数据的同时,我就先进行一些预处理,使得到后面进行计算的时候,可以简化一些步骤呢?答案是可以的。
        我们开一个二维数组存放矩阵,第$0$行和第$0$列全都置$0$,真正的矩阵在数组中下标从$1$开始。
        通常对矩阵有两种预处理:
        一种是把矩阵拍扁,即把前一列或前一行加到后一列或后一行上:
按列压缩↑,紫色部分和=棕色部分和-橙色部分和
按行压缩↑,紫色部分和=棕色部分和-橙色部分和
        以按行压缩为例,读入当前元素$t=A_{ij}$后,我们令$B_{ij}=A_{ij}+B_{i-1,j}$,以此类推,当所有数据读入后,预处理即完成,$B_{ij}$表示对于矩阵$A$的第$j$列,从第1行到第$i$行的和。这样我们若想要知道矩阵$A$第$j$列上,从第$p$行到第$q$行的和,直接用$B_{qj}-B_{p-1,j}, (p\leq q)$一步求出,而不需要进行$q-p+1$步计算,那么从左上角$A_{ab}$到右下角$A_{pq}$的子矩阵元素和为$sum$$=$$\sum\limits_{i=a}^{p}\sum\limits_{j=b}^{q}$$A_{ij}$$=$$\sum\limits_{j=b}^{q}$$B_{pj}$$-$$\sum\limits_{j=b}^{q}$$B_{a-1,j}$大大减少了计算量,降低了时间复杂度。
        比较丑的示例代码:
 #include <stdio.h>
const int N=;
int matA[N][N], matB[N][N];
int main()
{
puts("Please input a matrix:");
for(int i=; i<N; i++)
for(int j=; j<N; j++) {
scanf("%d", matA[i]+j);
matB[i][j]=matB[i-][j]+matA[i][j];
}
puts("The Preprocessed matrix is:");
for(int i=; i<N; i++)
for(int j=; j<N; j++)
printf("%d%c", matB[i][j], j==N-?'\n':' '); int a, b, p, q, res;
while(puts("Please input a, b and p, q:"),
~scanf("%d%d%d%d", &a, &b, &p, &q) )
{
res=;
puts("Sum from A_ab to A_pq is:");
for(int j=b; j<=q; j++)
res+=matB[p][j]-matB[a-][j];
printf("%d\n\n", res);
}
return ;
}
        运行结果:
 
       而另一种则是压缩到一个元素上,用$B_{ij}$表示从最左上角元素$A_{11}$到元素$A_{ij}$的和$\sum\limits_{m=1}^{i}\sum\limits_{n=1}^{j}$$A_{mn}$$, $$(i \geq 1, j \geq 1)$:
读入预处理↑,右图紫色块=4+24+30-18=40
        为了保持这一性质,我们在读入当前元素$t=A_{ij}$后,令$B_{ij}$$=$$A_{ij}$$+$$B_{i,j-1}$$+$$B_{i-1,j}$$-$$B_{i-1,j-1}$。当所有数据读入后,预处理即完成。
计算区域和↑,紫色区域和=60-12-15+3=36
        此时我们若想要求出从左上角$A_{ab}$到右下角$A_{pq}$的子矩阵元素和,只需三步计算:$sum$$=$$\sum\limits_{i=a}^{p}\sum\limits_{j=b}^{q}$$A_{ij}$$=$$B_{pq}$$-$$B_{p,b-1}$$-$$B_{a-1,q}$$+$$B_{a-1,b-1}$,即可使时间复杂度降低到常数。
        比较丑的示例代码:
 #include <stdio.h>
const int N=;
int matA[N][N], matB[N][N];
int main()
{
puts("Please input a matrix:");
for(int i=; i<N; i++)
for(int j=; j<N; j++) {
scanf("%d", matA[i]+j);
matB[i][j]=matA[i][j]+matB[i][j-]+matB[i-][j]-matB[i-][j-];
}
puts("The Preprocessed matrix is:");
for(int i=; i<N; i++)
for(int j=; j<N; j++)
printf("%3d%c", matB[i][j], j==N-?'\n':' '); int a, b, p, q, res;
while(puts("Please input a, b and p, q:"),
~scanf("%d%d%d%d", &a, &b, &p, &q) )
{
puts("Sum from A_ab to A_pq is:");
res=matB[p][q]-matB[p][b-]-matB[a-][q]+matB[a-][b-];
printf("%d\n\n", res);
}
return ;
}
        运行结果:

ACM 中 矩阵数据的预处理 && 求子矩阵元素和问题的更多相关文章

  1. 矩阵快速幂在ACM中的应用

    矩阵快速幂在ACM中的应用 16计算机2黄睿博 首发于个人博客http://www.cnblogs.com/BobHuang/ 作为一个acmer,矩阵在这个算法竞赛中还是蛮多的,一个优秀的算法可以影 ...

  2. 市场清仓价格算法 python求矩阵不同行不同列元素和的最大值

    问题描述 求矩阵不同行不同列元素和的最大值(最小值) 问题求解 1.通过scipy库求解 scipy.optimize库中的linear_sum_assignment方法可以求解 输入一个矩阵,参数m ...

  3. 关于 矩阵在ACM中的应用

    关于矩阵在ACM中的应用 1.矩阵运算法则 重点说说矩阵与矩阵的乘法,不说加减法. 支持: 结合律  (AB)C = A(BC) 分配律 A(B+C) = AB + AB $\left( \lambd ...

  4. Matlab中矩阵的平方和矩阵中每个元素的平方介绍

    该文章讲述了Matlab中矩阵的平方和矩阵中每个元素的平方介绍.   设t = [2 4 2 4] 则>> t.^2 ans = 4 164 16 而>> t^2 ans = ...

  5. C语言:将ss所指字符串中所有下标为奇数位置的字母转换为大写-将该字符串中的所有字符按ASCII码值升序排序后输出。-将a所指的4*3矩阵第k行的元素与第0行元素交换。

    //函数fun:将ss所指字符串中所有下标为奇数位置的字母转换为大写,若不是字母,则不转换. #include<conio.h> #include<stdio.h> #incl ...

  6. matlab中矩阵的表示与简单操作

    原文地址为:matlab矩阵的表示和简单操作 一.矩阵的表示在MATLAB中创建矩阵有以下规则: a.矩阵元素必须在”[ ]”内: b.矩阵的同行元素之间用空格(或”,”)隔开: c.矩阵的行与行之间 ...

  7. Java在ACM中的应用

    Java在ACM中的应用 —. 在java中的基本头文件(java中叫包) import java.io.*; import java.util.*; //输入Scanner import java. ...

  8. stl 在 acm中的应用总结

    总结一些在acm中常用的小技巧,小函数 之前尝试着总结过很多次.都失败了,因为总是担心不全,理解的也不是很透彻.这次再来一次...其实之前保存了很多的草稿就不发布了,当然,下面说的很不全面,路过的大牛 ...

  9. Python numpy中矩阵的用法总结

    关于Python Numpy库基础知识请参考博文:https://www.cnblogs.com/wj-1314/p/9722794.html Python矩阵的基本用法 mat()函数将目标数据的类 ...

随机推荐

  1. 编写Windows服务疑问2:探索服务与安装器的关系

    首先,来弄两个服务,一个叫“飞机”,一个叫“火车”. public class FeiJiService : ServiceBase { public FeiJiService() { Service ...

  2. 【Win10 应用开发】使用“实时可视化树”工具查看应用界面元素

    记得有朋友问老周,系统中的“计算器”应用的界面菜单是怎么做的.其实,你可以用VS 2015的新工具来查看它的界面结构. 实时可视化树工具只能查看XAML定义的界面,如WPF和Win App.现在,Wi ...

  3. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  4. Android性能优化之App应用启动分析与优化

    前言: 昨晚新版本终于发布了,但是还是记得有测试反馈app启动好长时间也没进入app主页,所以今天准备加个班总结一下App启动那些事! app的启动方式: 1.)冷启动      当启动应用时,后台没 ...

  5. 3、C#核心编程结构下

     本学习主要参考Andrew Troelsen的C#与.NET4高级程序设计,这小节主要述说以下几个东西: 这一小节是上一小节的补充,主要涉及到一下的知识细节: 1.C#方法的各种细节 2.探讨out ...

  6. iOS引入JavaScriptCore引擎框架(一)

    JavaScriptCore引擎     我们都知道WebKit是个渲染引擎,简单来说负责页面的布局,绘制以及层的合成,但是WebKit工程中不仅仅有关于渲染相关的逻辑,也集成了默认的javascri ...

  7. 【目录】JUC集合框架目录

    JUC集合框架的目录整理如下: 1. [JUC]JUC集合框架综述 2. [JUC]JDK1.8源码分析之ConcurrentHashMap(一) 3. [JUC]JDK1.8源码分析之Concurr ...

  8. RabbitMQ原理与相关操作(一)

    小编是菜鸟一枚,最近想试试MQ相关的技术,所以自己看了下RabbitMQ官网,试着写下自己的理解与操作的过程. 刚开始的第一篇,原理只介绍 生产者.消费者.队列,至于其他的内容,会在后续中陆续补齐. ...

  9. ASP.NET MVC5----了解我们使用的@HTML帮助类

    20几岁,怕什么. 自己的感觉 说一个自己最近使用AngularJS的感受,我们之前使用mvc进行项目开发都是了解和经常使用HTML的帮助类,来完成我们前端大部分代码的编写,其实在我没有接触Angul ...

  10. ASP.NET Core Kestrel部署HTTPS

    ASP.NET Core配置 Kestrel部署HTTPS.现在大部分网站已经部署HTTPS,大家对于安全越来越重视. 今天简单介绍一下ASP.NET Core 部署HTTPS,直接通过配置Kestr ...