首页 > 编程语言 >算法基础1.4.1前缀和与二维前缀和

算法基础1.4.1前缀和与二维前缀和

时间:2023-03-04 16:36:47浏览次数:44  
标签:1.4 前缀 int y1 二维 数组 x2 x1

前言

前缀和其实不能说是一种算法,它也并不会单独出现题目中。应该说是一个比较简单,但是容易被人忽略的工具

正文

所谓前缀和,就是一个用来计算数组某个区间内所有数之和的一个工具

以一维来举例

假如我们有一个一维数组a,数组中从1n存着一共n个数据(第0位不存数据,这个我们后面再解释)。

那么我们就创造一个一维数组bb的第x位置的数据代表a数组从第1位到第x位所有数之和

那么如果我们需要知道数组第m位到第n位之间所有数的和,我们就可以通过b[n] - b[m-1]来得到答案。

  • 如果我们需要知道第1位到第m位所有数之和(闭区间),那么如果我们不想对这种情况使用if进行特殊判断,就要根据之前的式子进行b[m] - b[0]的计算。显然,我们需要b[0] == 0
  • 按照我们的对应关系,一维数组bb的第x位置的数据代表a数组从第1位到第x位所有数之和。那么如果我们的a数组是从第0位开始存数据的,那么我们就不能让b[0] == 0了。所以我们让a从第1位开始其实是为了b[0]的存在服务的
  • 注意,其实可以在输入的时候就进行前缀和的运算,这样我们就不用开两个数组了,这个看个人习惯与试题实际情况

一维前缀和

这个属于一个小工具,所以代码十分简单,也基本不需要背代码,知道这个思想自己写也不难

#include<iostream>

using namespace std;

const int N=1e6;
int a[N],b[N];
int n,m;

int main(){
    cin >> n >> m;
    // 输入数据
    for(int i=1;i<=n;i++) cin>>a[i];
    // 前缀和数组初始化
    for(int i=1;i<=n;i++) b[i] = b[i-1] + a[i];
    int l,r;
    while(m--){
        cin>>l>>r;
        // 计算区间中所有数之和
        cout<<b[r] - b[l-1]<<endl;
    }
    return 0;
}

二维前缀和

这个可能会稍微难一点,因为要借助图形来方便理解。

我们的目的是对于一个二维数组,先生成一个b数组,他(x , y)代表这个点与原点区域内的所有值之和,也就是图中区域所有数之和(我们这次写的代码包含边界)

b[i][j] = b[i-1][j] + b[i][j-1] - b[i-1][j-1] + a[i][j];

image-20230304153653576

那么我们对程序输入两个坐标,我们就可以通过b数组算出来以这两个点为对角点的矩形内所有数的和

image-20230304154024233

计算方法也很简单,通过图形就会很直观

其实就是b[x2 , y2] - b[x2 , y1-1] - b[x1-1 , y2] + b[x1 , y1]

image-20230304160234541

注意,如果但从图像上可能会认为是b[x2 , y2] - b[x2 , y1] - b[x1 , y2] + b[x1 , y1],但是其实这本质上是数组,不是连续的,所以如果这样写,计算的和是不包括一部分边界值

思路讲完了,上代码

#include<iostream>

using namespace std;

const int N=1010;
int a[N][N],b[N][N];

int main(){
    int n,m,q;
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            b[i][j] = b[i-1][j] + b[i][j-1] - b[i-1][j-1] + a[i][j];
        }
    }
    int x1,y1,x2,y2;
    while(q--){
        cin>>x1>>y1>>x2>>y2;
        cout<< b[x2][y2] - b[x1-1][y2] - b[x2][y1-1] + b[x1-1][y1-1] <<endl;
    }
    return 0;
}

结语

难得有一个是我听完思路后可以自己完美写出来的东西。

但是这篇文章画图快画死我了。。。

标签:1.4,前缀,int,y1,二维,数组,x2,x1
From: https://www.cnblogs.com/zaughtercode/p/17178500.html

相关文章

  • .NET静态代码织入——肉夹馍(Rougamo) 发布1.4.0
    肉夹馍(https://github.com/inversionhourglass/Rougamo)通过静态代码织入方式实现AOP的组件,其主要特点是在编译时完成AOP代码织入,相比动态代理可以减少应用启动的初始化时......
  • 6-二维离散型随机变量
    12一个看成是变量,另一个就看成是常量。3一个人的事情是边缘,两个人的事情是联合。1......
  • [Go语言tips04]二维数组与二维切片
    0.引言既然在Go语言中数组和切片同时存在并且是两个不同的类型,那当他们是二维时又会产生什么样的问题?因为数组和切片同时存在,在Go语言中二维的使用就会显得和别的语言很......
  • 推荐一个开源的 .NET 二维码生成库
    推荐一个开源的.NET二维码生成库dotnet编程大全专注C#WPF编程,dotnet编程大全​关注他 2人赞同了该文章       你好,......
  • Excel 数据转二维数组 JSON
    问题描述:偶尔会遇到读取Excel数据的场景如果是在网页中,可以上传文件然后处理(可借助js-xlsx等插件)如果有node服务,也可以使用类似的操作不过如果是在应用外,只是临......
  • 微信二维码生产的两种方式
    https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/url-link/generateUrlLink.htmlhttps://developers.weixin.qq.com/miniprogram/introduction......
  • 1.4 算法和算法分析
    1.4算法和算法分析算法定义对特定问题求解方法和步骤的一种描述,它是指令的有限序列。其中每个指令的表示一个或多个操作。简而言之,算法就是解决问题的方法和步骤。......
  • 防错料使用二维码解决方案 生产过程物料防错管理 免费提供源码
    生产过程中,物料的防错管理是非常重要的一环。它能够有效地防止物料错用或混用,从而降低产品质量问题的发生率,减少生产成本和生产周期,提高生产效率和产品质量。以下是生产过......
  • 申报发布项目单点登录调试时候,前端请求前缀带了sbgl,没有重写sbgl,然后后端数据库的路由
       1.从数据库修改表数据,redis不会更新这个数据,所以得重启redis才能看到最新效果,但是你从前端界面修改路由的话,那就不用立马重启redis,因为一般自己设计的框架都会自......
  • 搜索二维矩阵---二分查找
    搜索二维矩阵编写一个高效的算法来判断 mxn 矩阵中,是否存在一个目标值。该矩阵具有如下特性:每行中的整数从左到右按升序排列。每行的第一个整数大于前一行的最后一......