前缀和算法【一维、二维】

这篇具有很好参考价值的文章主要介绍了前缀和算法【一维、二维】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

算法推导

首先这种算法适合于求从 x 到 y 的和

一维情况

一维代码十分简单,我们只需要每个都记录前面所有的和即可,注意细节 下标从1开始

for(int i = 1 ; i <= n ; i ++){
	cin >> temp;
	a[i] = a[i - 1] + temp;
}

这里我们就看两种情况:一种是 开始时 ,一种是 执行中

在开始时,因为我们是从1开始,a[0] = 0,所以第一个就是temp;

在执行过程中,因为前一个是前面所有的数字之和,加上temp就变成当前数字之和了

二维情况

二维的前缀和则分为两个部分,一个是计算前缀和,另一个则是计算从(x1,y1)到(x2,y2)的值

计算前缀和

假设我们输入的值为

1 1 1 1
1 1 1 1
1 1 1 1

现在我们需要处理的前缀和


0 1 2 3 4
0
0 0 0 0 0
1 0 1 2 3 4
2 0 2 4
3 0 3
4 0 4

问题一:如何计算前缀和数组的元素?

若我们需要计算a[i][j],我们需要计算a[i-1][j] + a[i] [j-1] + temp - a[i-1][j-1]。

上面元素 + 左边元素 - 左上角元素

  • a[i-1][j]:表示前面 列的前缀和
  • a[i] [j-1]:表示前面的 行的前缀和

所以两个直接相加 ,再加上temp,就能得到此单元格的内容

但是需要注意的是,前面两个会将a[i-1][j-1]都加进去,所以这里需要 减去一个 即可

现在我们计算a[1] [1] = a[0][1] + a[1][0] + a[0][1] - a[0][0] + 1 = 1

计算行

a[2] [1] = a[1][1] + a[2][0] + 1 - a[1][0] = 2

计算列

a[1][2] = a[1][1] + a[0][2] + 1 - a[0][1] = 2

a[2][2] = a[2][1] + a[1][2] - a[1][1] + 1 = 2 + 2 - 1 +1= 4


0 1 2 3 4
0
0 0 0 0 0
1 0 1 2 3 4
2 0 2 4
3 0 3
4 0 4

同样的处理后我们将得到以下表格


0 1 2 3 4
0
0 0 0 0 0
1 0 1 2 3 4
2 0 2 4 6 8
3 0 3 6 9 12
4 0 4 8 12 16

得到代码

for(int i = 1 ; i <= n ; i ++){
	for(int j = 1 ; j <= m ; j ++){
		cin >>temp ;

		a[i][j] = a[i - 1][j] + a[i][j - 1] + temp - a[i-1][j-1];
	}
}

计算结果

现在假设我们需要计算(x1,y1)和(x2,y2)的和。

因为前面我们已经获得了前缀和的一个数组,但是都是基于(1,1)这个点,现在需要改变起点,就需要进行重新计算

前缀和算法【一维、二维】

假设当前我们需要计算(2,3)到(4,4)

前缀和算法【一维、二维】

首先我们需要明确这两个位置表示的数字意思

  • (2,3):表示从(1,1)开始到(2,3)的前缀和

    前缀和算法【一维、二维】

  • (4,4):表示从(1,1)开始到(4,4)的前缀和)

    前缀和算法【一维、二维】

从两个图中,很容易发现这两者有相交的地方

前缀和算法【一维、二维】

所以,我们需要进行相减

我们需要减去这两个内容(蓝色框 + 黑色框)

前缀和算法【一维、二维】

对应到数组内分别对应

  • 蓝色:a[x1 - 1][y2]
  • 黑色:a[x2][y1-1]

但是很明显的,这中间同样也减了两次相同的内容:a [x1 - 1] [ y1 - 1],所以需要加上

解决代码文章来源地址https://www.toymoban.com/news/detail-417791.html

while(q--){
	cin >> x1 >> y1 >> x2 >> y2;

	cout << a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1];
}

完整代码

一维

#include <iostream>

using namespace std;

const int N = 100009;

int a[N];

int main()
{
    int n , m , temp = 0;

    cin >> n >> m;

    for(int i = 1 ; i <= n ; i ++){
        cin >> temp;
        a[i] = a[i - 1] + temp;
    }

    int l , r ;
    while(m--){
        cin >> l >> r;
        cout << a[r] - a[l - 1] << endl;
    }

    return 0;
}

二维

#include<iostream>

using namespace std;

const int N = 1008;

int a[N][N];
int n ,  m , q;


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

到了这里,关于前缀和算法【一维、二维】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构与算法—一维数组、二维数组、矩阵、顺序串、链接串的C++代码实现

    1、一维数组:ArrayOneD.h 数组这种数据结构可以看作线性表的推广。数组一般采用顺序存储的方法表示。 这是一个模板类 ArrayOneD 的实现,用于表示一维数组。它包括了 构造函数、拷贝构造函数、析构函数、重载下标运算符、重载赋值运算符、求数组长度、重新设置数组长度

    2024年02月07日
    浏览(62)
  • 算法训练第四十二天|01背包问题 二维 、01背包问题 一维、416. 分割等和子集

    视频链接:https://www.bilibili.com/video/BV1cg411g7Y6/ 参考:https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 对于面试的话,其实掌握01背包,和完全背包,就够用了,最多可以再来一个多重背包。 而完全背包又是也是01背包稍作变化而来,即:完全

    2024年02月01日
    浏览(46)
  • 一维热传导方程的推导

    考虑一根具有定横截面积 A A A 的杆,其方向为 x x x 轴的方向(由 x = 0 x=0 x = 0 至 x = L x=L x = L ),如图1所示。 设单位体积的热能量为未知变量,叫做热能密度: e ( x , t ) e(x,t) e ( x , t ) 。 假设通过截面的热量是恒定的,杆是一维的。做到这一点的最简单方法是将杆的侧面完

    2024年02月15日
    浏览(45)
  • 前缀和(一维)

    本篇文章我们来介绍一个简单的算法,前缀和。 什么是前缀和? 前缀和是某一个序列的前n项的和,可以理解为数学上的数列的前n项和。 如果 (a) 和 (s) 分别是原数组和前缀和数组,那么应该有如下关系: s[1] = a[1]; 、 s[2] = a[1] + a[2]; 、 s[3] = a[1] + a[2] + a[3]; 如何得到前缀和

    2024年02月08日
    浏览(30)
  • python二维索引转一维索引 & 多维索引转一维索引

    原博客地址:https://blog.csdn.net/qq_42424677/article/details/123011642

    2024年02月11日
    浏览(44)
  • Java——一维数组和二维数组(主要详讲一维数组)

    目录 一维数组 创建,初始化,赋值 注意 一些数组的便捷使用方法 使用 .length得到数组长度 Arrays相关的使用 二维数组 文章某些地方会出现java与c语言的比较 文章内容参考韩顺平老师的课堂笔记 可以先创建再初始化,也可以创建的时候直接初始化。但是,如果选择先创建再

    2024年02月01日
    浏览(51)
  • 前缀和--二维矩阵的前缀和

    原题链接 输入一个 n 行 m 列的整数矩阵,再输入 q 个询问,每个询问包含四个整数 x1,y1,x2,y2 ,表示一个子矩阵的左上角坐标和右下角坐标。 对于每个询问输出子矩阵中所有数的和。 输入格式 第一行包含三个整数 n,m,q 。 接下来 n 行,每行包含 m 个整数,表示整数矩阵。

    2024年01月16日
    浏览(44)
  • 【PHP】二维数组转一维数组

    在 PHP 中,如果你想将一个二维数组转换为一维数组,你可以使用几种不同的方法。以下是一些常见的方法: array_column() 用于提取数组中的列,最为直接 array_map() 用于对数组中的每个元素应用回调函数,返回的是由回调函数的返回值组成的新数组。 以上任何一种方法都可以

    2024年02月04日
    浏览(65)
  • matlab 二维矩阵变成一维矩阵

    1、一维变二维: https://blog.csdn.net/qq_40584593/article/details/90691276 reshape 2、a(:)即可 https://jingyan.baidu.com/article/d45ad148dc221b29552b80ec.html

    2024年02月11日
    浏览(47)
  • 动态规划—— 01背包问题(一维,二维)

    0-1背包问题是一个经典问题,特别是在算法和动态规划领域。问题是关于一个小偷,他有一个可以携带最大重量的背包,并且他有一组物品,其中每个物品都有自己的价值和重量。小偷希望在不超过背包所能承载的最大重量的情况下,最大化他从这些物品中获得的总价值。问

    2024年02月19日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包