- 一、3956.截断数组(前缀和)
- 二、前缀和(前缀和)
- [0]+list(map(int,input().split()))
- 三、子矩阵的和(前缀和)
- range(1,n+1)
- 四、K倍区间(前缀和)
- 五、激光炸弹(前缀和)
- a=[[0]*5002 for _ in range(5002)]
一、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)