【Python 百练成钢】前缀和

简介: 【Python 百练成钢】前缀和

前言😇


今天分享一下学到的基础算法前缀和。

首先了解一下前缀和的基础概念😄

有一个序列,序列内包含很多数a1、a2、a3、a4、a5、a6、a7

a1的前缀和就是a1

a2的前缀和就是a1+a2

a3的前缀和就是a1+a2+a3

此时可以定义一个序列bn专门用于存放关于an的前缀和

b1、b2、b3、b4、b5、b6、b7…

使得:


b1=a1

b2=a1+a2

b3=a1+a2+a3


这样就得到了一个关于a序列的前缀和序列,在进行一些运算的时候可以大大的降低时间复杂度。

写题的时候步骤就是


(1)确定前缀和序列

(2)使用位置关系对前缀和序列进行查询,得到想要的结果

具体如何用听我细细道来

e7837bb6a2e043ef9d80f12be9863a04.png


一维前缀和😈



问题描述


输入一个长度为n的整数序列。

接下来再输入m个询问,每个询问输入一对l, r。

对于每个询问,输出原序列中从第l个数到第r个数的和。

输入格式

第一行包含两个整数n和m。

第二行包含n个整数,表示整数数列。

接下来m行,每行包含两个整数l和r,表示一个询问的区间范围。

输出格式

共m行,每行输出一个询问的结果。

数据范围

1≤l≤r≤n,

1≤n,m≤100000,

−1000≤数列中元素的值≤1000

输入样例:

5 3

2 1 3 6 4

1 2

1 3

2 4

输出样例:

3

6

10


问题分析


对于一维前缀和直接构造前缀和序列即可,然后打印l与r位置的前缀和元素之差。

可以将所有的结果先添加到一个序列中,在输入所有操作之后一块打印。


代码实现


老规矩先上运行结果:


a8dd2617169c4d6fb1ac8457b3938c27.png


# 暴力解决
'''
import sys
n,m=sys.stdin.readline().strip().split()
n,m=int(n),int(m)
nls=[]
ans=[]
ls=[int(x) for x in sys.stdin.readline().strip().split()]
for i in range(m):
    l,r=sys.stdin.readline().strip().split()
    l,r=int(l),int(r)
    sum=0
    for i in range(l-1,r):
        sum+=ls[i]
    ans.append(sum)
print(ans)
'''
# 前缀和
'''
先将数据处理一下,然后在进行计算的时候就是进行查询
显然进行查询要方便的多。
'''
import sys
n,m=sys.stdin.readline().strip().split()
n,m=int(n),int(m)
ls=[int(x) for x in sys.stdin.readline().strip().split()]
als=[]
ans=[]
als.append(0)
ans.append(0)
# print(ls,als,ans)
als.append(ls[0])
for j in range(1,n):
    als.append(als[len(als)-1]+ls[j])
for i in range(m):
    l,r=sys.stdin.readline().strip().split()
    r,l=int(r),int(l)
    ans.append(als[r]-als[l-1])
# print(ans)
for i in range(1,m+1):
    print(ans[i])


二维前缀和👿



问题描述


输入一个n行m列的整数矩阵,再输入q个询问,每个询问包含四个整数x1, y1, x2, y2,表示一个子矩阵的左上角坐标和右下角坐标。

对于每个询问输出子矩阵中所有数的和。

输入格式

第一行包含三个整数n,m,q。

接下来n行,每行包含m个整数,表示整数矩阵。

接下来q行,每行包含四个整数x1, y1, x2, y2,表示一组询问。

输出格式

共q行,每行输出一个询问的结果。

数据范围

1≤n,m≤1000,

1≤q≤200000,

1≤x1≤x2≤n,

1≤y1≤y2≤m,

−1000≤矩阵内元素的值≤1000

输入样例:

3 4 3

1 7 2 4

3 6 2 8

2 1 2 3

1 1 2 2

2 1 3 4

1 3 3 4

输出样例:

17

27

21


问题分析


应准备一个矩阵,一个用于存放以(1,1)与(x1,y1)矩阵中的元素和

在进行求取面积内元素和的时候,使用矩阵元素之间的关系。

此时面临两个问题(可以配合图片进行理解):

对于以下图片中均是左边代表原始矩阵,右边代表和矩阵

一、矩阵求求和

对应颜色矩阵的框所有数的和求出来后放进对应颜色的位置

由于矩阵叠加,所以我们在进行求和的时候应先加然后再减去叠加的部分故可得:

b33=a33+b32+b23-b22

3d1c617421a64cfc88216b916aec0d72.png


二、矩阵求差(这也是最终面临的问题)

由于矩阵叠加,所以我们在进行求差的时候应先减去矩阵周围的矩阵和,然后加上重复减去的部分:

故可得下标为a22与a33围成的矩阵所有元素和为:b22-33=b33-b31+b13+b11

这里进行求解的时候可能面临坐标交换,a22-a33围成的矩阵,与a32-a23围成的是一个矩阵

所以我们不妨将ax1y1中的下标均换成最小的便于计算。(也就是说转换成x1<x2,y1<y2)

然后以最小的坐标与最大的坐标为界,减去所求矩阵周围的矩阵


14365dc197d6415aaec98d7d2e45768d.png


代码实现


老规矩先上运行结果:

0fae9ab117f042448094bae3279b91c0.png

import sys
ans=[]
# 原始矩阵
amatrix=[]
# 前缀和矩阵
bmatrix=[]
# 读入n,m,q并将其转换为数值类型
n,m,q=sys.stdin.readline().strip().split()
n,m,q=int(n),int(m),int(q)
# 初始化前缀和矩阵
for i in range(n+1):
    bmatrix.append([0]*(m+1))
# 读入原始矩阵
for i in range(n):
    amatrix.append([int(x) for x in sys.stdin.readline().strip().split()])
#利用原始矩阵,求前缀和矩阵
i=1
# 行
while i<=n:
    j=1
    # 列
    while j<=m:
        bmatrix[i][j]=amatrix[i-1][j-1]+bmatrix[i][j-1]+bmatrix[i-1][j]-bmatrix[i-1][j-1]
        j+=1
    i+=1
# 测试是否创建前缀和矩阵成功
# for i in bmatrix:
#     print(i)
# 写入坐标矩阵
qm=[]
for i in range(q):
    qm.append([int(x) for x in sys.stdin.readline().strip().split()])
# 计算某段矩阵的和
i=0
while i<q:
    # 处理矩阵中的xy,确保x2y2在矩阵的右下方便于后面计算
    if qm[i][0]>qm[i][2]:
        qm[i][0],qm[i][2]=qm[i][2],qm[i][0]
    if qm[i][1]>qm[i][3]:
        qm[i][1],qm[i][3]=qm[i][3],qm[i][1]
    ans.append(bmatrix[qm[i][2]][qm[i][3]]-bmatrix[qm[i][0]-1][qm[i][3]]-bmatrix[qm[i][2]][qm[i][1]-1]+bmatrix[qm[i][0]-1][qm[i][1]-1])
    # print(qm[i])
    i+=1
# 结果输出
print(ans)





目录
相关文章
|
6月前
|
机器学习/深度学习 Python 算法
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
|
6月前
|
关系型数据库 测试技术 Python
2024年最新【Python 百练成钢】快速上手并查集(2),Python面试简历模板
2024年最新【Python 百练成钢】快速上手并查集(2),Python面试简历模板
|
6月前
|
Python
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交
|
6月前
|
存储 算法 Python
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交(2)
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交(2)
|
6月前
|
存储 算法 Python
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交(1)
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交(1)
|
算法 Python
【Python 百练成钢】蓝桥杯填空题
【Python 百练成钢】蓝桥杯填空题
171 0
|
存储 机器学习/深度学习 人工智能
【Python 百练成钢】DNA、蛇形矩阵、Huffuman树、K-进制数、K倍区间、交换瓶子、第几个幸运数、四平方和、The 3n + 1 problem、大数乘法
【Python 百练成钢】DNA、蛇形矩阵、Huffuman树、K-进制数、K倍区间、交换瓶子、第几个幸运数、四平方和、The 3n + 1 problem、大数乘法
288 0
【Python 百练成钢】DNA、蛇形矩阵、Huffuman树、K-进制数、K倍区间、交换瓶子、第几个幸运数、四平方和、The 3n + 1 problem、大数乘法
|
存储 算法 C语言
【Python 百练成钢】通过写题快速入门动态规划
【Python 百练成钢】通过写题快速入门动态规划
158 0
【Python 百练成钢】通过写题快速入门动态规划
|
存储 人工智能 算法
【Python 百练成钢】最短路径的几种求解方式
【Python 百练成钢】最短路径的几种求解方式
230 0
【Python 百练成钢】最短路径的几种求解方式
|
Python
【Python 百练成钢】二叉树合集:关于二叉树的夺命连环问,你能抗住几问?
【Python 百练成钢】二叉树合集:关于二叉树的夺命连环问,你能抗住几问?
91 0
【Python 百练成钢】二叉树合集:关于二叉树的夺命连环问,你能抗住几问?