算法心得(2)**前缀和**

news/2025/3/12 13:36:44/文章来源:https://www.cnblogs.com/Travic/p/18765359

**思路**

前缀和的思想就是  **把影响累加起来,每一次累加都作一次记录**

一般在情况满足两个条件时就使用它: (1)影响可以累加   (2)有多个查询

就拿计算二维矩阵面积来说:

图中红框框起的一个子矩阵的面积为9+8+4-2+3+11=33,同时以左上角(蓝框,坐标为(2,2))和右下角(黄框,坐标为(3,4))定位这个子矩阵,我们说(2,2)到(3,4)的子矩阵的面积为33。

那么问题来了,如果要我们要反复查询(x1,y1)到(x2,y2)的子矩阵面积,其中x1,y1,x2,y2是不断变化的,那我们是不是要每一次查询都要把子矩阵的内容一个一个加起来算面积?这样未免也太繁琐了。

因为每一次的计算,会对一些元素进行反复的计算,如:

计算红框和蓝框两个子矩阵的面积,会发现3+11被计算了两次,这个重叠部分可以优化,于是便有了前缀和。

我们首先计算每一个以(1,1)为左上角的子矩阵的面积:

把计算结果保存在一个与原矩阵同样大小的矩阵,该矩阵成为前缀和矩阵:

保存原则是这样的:左上角坐标为(0,0),右下角坐标为(i,j)的子矩阵的面积保存在(i,j)的位置,比如原矩阵中(0,0)到(4,3)的子矩阵的面积为53,保存到上图的(4,3)的位置。

那么最主要的问题就是,怎么查询一个左上角坐标不为(0,0)的子矩阵的面积?

比如要查这个:    那我们可以进行一些变换:

红框的面积就是蓝框+黄框+绿框-紫框,由于蓝框、黄框、紫框的面积已经保存在了前缀和矩阵中,而绿框面积又不用计算,所以对于红框的子矩阵:(2,2)到(4,3)的面积=前缀和(4,2)+前缀和(3,3)+7-前缀和(3,2)。

给出相对普适一点的代码模板:

#include <stdio.h>
const int N = 100010;
int a[N][N]; // 原矩阵
int S[N][N]; // 前缀和矩阵
int main()
{int n; // 矩阵行数int m; // 矩阵列数int i, j;for (i = 1; i < n; i++) // 注意,下标是从1开始的,这是为了利用为0的S[0][n]和S[n][0]for (j = 1; j < m; j++){scanf("%d", a[i][j]);S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + a[i][j]; // 求前缀和}for (i = 1; i < n; i++){for (j = 1; j < m; j++)printf("%d, ", S[i][j]);printf("\n");}return 0;
}

由此可以看出,前缀和的思想就是把影响累加,然后通过不同的累加之间的运算,减少每次查询之间重叠的开销。

**例题**

第31次CSP认证考试中的第二题,“坐标变换(其二)”:

经过思考,每一次对坐标的操作是可以累加的,并且有多次查询,所以适合使用前缀和。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/897674.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

爬取Microsoft Bing网站图片

说明: 这个小案例主要是访问Microsoft Bing网站去爬取“车牌”图片,代码写的时候不规范,但是效果还行文件结构为下图:具体思路#爬取html.py import requests import time from tqdm import tqdm import os url=https://cn.bing.com/images/async headers={User-Agent:Mozill…

打开组策略,提示找不到资源$(string.WHFB_DisablePostLogonCredentialCaching)(在属性 displayName 中引|用)

情况 win11家庭版不提供组策略,因此我使用了网络上提供的命令进行开启。 开启后使用win自带的搜索,搜索组策略或是gpedit都没有反应,使用命令行输入gpedit可以正常跳出窗口,然而打开组策略提示如下。未解决 https://bbs.pcbeta.com/viewthread-1688611-1-1.html https://an…

Processing (Java) 中实现2D任意图形的鼠标悬停检测 2D射线检测 模拟按钮 点击事件

引言 如果使用Processing开发应用,画面中需要设定一些按钮,而且这些按钮是不规则图形样式,甚至是以一张图片形式呈现,如何判定其轮廓,定义悬停事件、点击事件是非常核心的算法需求。本文浅析这一问题的通用解决方案。因为Processing是Java衍生语言,同样适合java语言体系。…

运行窗口无法打开软件程序的解决办法

事情起因:  本人安装了 Notepad-- 文本编辑软件,但是通过Win+R,打开运行窗口,输入Notepad-- 无法打开该软件;报错如下: 解决办法  此电脑-属性-高级系统设置-高级-环境变量  在 系统变量 里,找到 Path 变量 添加软件安装路径,并上移 确定保存,电脑重启,系统环…

牛客题解 | 为数据集行创建复合超向量

牛客题库题解题目 题目链接 复合超向量是一种将多个向量组合成一个向量的方法,其计算公式为: \[composite\ hypervector = \sum_{i=1}^{n} w_i \times v_i \]其中,\(w_i\) 是权重,\(v_i\) 是向量。 在本题中,这是一个使用超维计算(HDC)的任务,需要通过以下步骤处理数据…

【设计模式】从事件驱动到即时更新:掌握观察者模式的核心技巧

概述 定义:又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 结构 在观察者模式中有如下角色:Subject:抽象主题(抽象被…

【设计模式】探索状态模式在现代软件开发中的应用

概述 【例】通过按钮来控制一个电梯的状态,一个电梯有开门状态,关门状态,停止状态,运行状态。每一种状态改变,都有可能要根据其他状态来更新处理。例如,如果电梯门现在处于运行时状态,就不能进行开门操作,而如果电梯门是停止状态,就可以执行开门操作。 类图如下:代码…

团队展示 (组长:金帝彪)

一、团队介绍 1.1 团队概况 1.1.1 博客展示链接 团队名称,彩虹小分队 https://www.cnblogs.com/JINjin20040207 1.1.2 团队项目描述 健康体重管理平台 1.1.3 队员风采 姓名:金帝彪 风格:谋定后动 擅长的技术:业务分析 编程的兴趣:C 希望的软工角色:业务分析师 一句话宣言:…

3.12 数字逻辑电路

1.时序逻辑电路 1.1 与组合逻辑电路(比如译码器,多路选择器,全加法器)的区别:时许逻辑电路可以存储信息 1.2 基本存储元件 1.2.1 RS锁存器(存储一个byte位的信息)(低电频使能) R:reset复位;S:set置位 R和S是两个输入端,A和B希望是两个取反状态 当S=0,表示要置位(低…

day:19 html实战

一、认识标签 1、标题标题 h1--h6 格式: <!doctype html>认识标签第一大标题 第二大标题 第三大标题 第四大标题 第五大标题 第六大标题 </body>2、常用标签 代码:常用标签段落标签,也叫p标签 斜体标签,也叫em标签 b标签,也是加粗 斜体标签 加粗标签 下划线 删…

Properties-读取配置文件中的内容

读取配置文件中的内容Properties-读取配置文件中的内容 新建子项目properties 修改POM 父POM中加上子项目module。子项目依赖父项目,打包方式jar。引入spring-boot-configuration-processor和lombok(Lombok 的安装与使用)spring-boot-configuration-processor的作用是生成配置…

matlab实现Arduino的PIL硬件仿真

使用 Arduino 硬件上的 PIL 进行代码验证和验证1. 尝试arduino的PIL程序例程-arduino_pil_bolck 1.1 准备安装包 安装arduino 硬件支持包安装编辑器MinG-w64 1.2实现步骤https: //ww2.mathworks.cn/help/simulink/supportpkg/arduino_ref/code-verification-and-validation-wit…