学习python第一天---前缀和

一、3956.截断数组(前缀和)

在这里插入图片描述
*** 题意:***
要求将一个数组切两刀,分成三份,然后这三份的数组元素和相同。
*** 思路:***
运用前缀和,枚举第一刀出现的位置,如果出现的位置前缀和为2/3sum,那么说明这里可以切一刀,为第二刀,并加上第一刀有多少种切法;如果前缀和为1/3sum,那么说明可以切一道,为第一刀。

n=int(input())#input的返回类型是str
a=list(map(int,input().split()))
s=sum(a)
if s%3:#不能被3整除说明不行
    print(0)
else:
    p=ans=pre=0
    for i in range(n-1):#i是第三段的起点,cnt表示有多少个j满足要求
        pre+=a[i]
        if pre==s*2//3:#'//'除完之后只取整数部分
            ans+=p
        if pre==s//3:
            p+=1
    print(ans)

二、前缀和(前缀和)

在这里插入图片描述
这道题目是典型的前缀和,记住这个板子好啦。

[0]+list(map(int,input().split()))

Python中的表达式[0]用于创建一个包含单个元素的列表,该元素为整数0。当您将[0]与+运算符组合时,它将此列表与list(map(int,input().split())表达式的结果连接起来。

在Python中,input()函数从标准输入(通常是键盘)中读取一行文本,字符串的split()方法根据分隔符将字符串拆分为子字符串列表。split()使用的分隔符默认为空格,因此input().split()将输入行分割为一个由空格分隔的字符串列表。

map()函数对split()返回的列表中的每个字符串应用int()函数,生成一个整数列表。

因此,当你将[0]和+运算符组合在一起时,你创建了一个新的列表,它由整数0和map(int,input().split())生成的整数列表组成。在列表开头添加整数0的目的可能取决于代码的上下文,但它可能用作占位符或标记值。

n,m=map(int,input().split())
pre=[0]+list(map(int,input().split()))#一维数组的读取
for i in range(1,n+1):
    pre[i]+=pre[i-1]
for _ in range(m):
    l,r=map(int,input().split())
    print(pre[r]-pre[l-1])

三、子矩阵的和(前缀和)

在这里插入图片描述
典型的二维前缀和

range(1,n+1)

当在Python中使用range()函数时,它会返回一个数字序列,默认从0开始递增1,直到一个指定的数字之前停止。
因此,当使用range(1, n+1)时,它将生成一个数字序列,从1开始,到n为止(包括n),即它将生成数字1、2、3、…、n。
请注意,range()中指定的上限总是在序列中排除,这意味着最后生成的数字将是n,而不是n + 1。

n,m,q=map(int,input().split())#n行m列的矩阵,q次询问
a=[[0] for i in range(n+1)]#先构造一个一维数组
a[0]=[0]*(m+1)#m行矩阵
for i in range(1,n+1):
    a[i]+=list(map(int,input().split()))#读入
for i in range(1,n+1):
    for j in range(1,m+1):
        a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]#初始化
for _ in range(q):
    x1,y1,x2,y2=map(int,input().split())
    print(a[x2][y2]+a[x1-1][y1-1]-a[x2][y1-1]-a[x1-1][y2])#二维前缀和

四、K倍区间(前缀和)

在这里插入图片描述
如果(a[i]-a[j])%k=0,说明这两个%k的余数是相等的。

n,k=map(int,input().split())#n行m列的矩阵,q次询问
s=[0]
for i in range(1,n+1):
    s.append(int(input()))
    s[i]+=s[i-1]
cnt=[0]*k
cnt[0]+=1#处理s[0]=0的这种情况,后面是从1开始的,就要先把s[0]放进去
res=0
for i in range(1,n+1):
    res+=cnt[s[i]%k]
    cnt[s[i]%k]+=1
print(res)

五、激光炸弹(前缀和)

在这里插入图片描述

a=[[0]*5002 for _ in range(5002)]

这行代码创建了一个名为a的二维列表,列表的行数和列数均为5002,且每个元素都被初始化为0。换句话说,这个列表是一个5002x5002的矩阵,可以用来存储二维数据。

(n,r),N,res=map(int,input().split(' ')),0,0
a=[[0]*5002 for _ in range(5002)]
for _ in range(n):
    x,y,w=map(int,input().split(' '))
    N=max(N,x+1,y+1)
    a[x+1][y+1]+=w

for i in range(1,N+1):#预处理前缀和数组
    for j in range(1,N+1):
        a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]

if r<N:#枚举所有边长是R的矩形,枚举(i,j)为右下角
    for i in range(r,N+1):
        for j in range(r,N+1):
            res=max(res,a[i][j]-a[i-r][j]-a[i][j-r]+a[i-r][j-r])
else:
    res=a[N][N]

print(res)

猜你喜欢

转载自blog.csdn.net/qq_51408826/article/details/129189489