当前位置:   article > 正文

Python:统计子矩阵(前缀和、尺取法)_统计子矩阵python

统计子矩阵python

问题描述

给定一个 N×M 的矩阵 A, 请你统计有多少个子矩阵 (最小 1×1, 最大  N×M) 满足子矩阵中所有数的和不超过给定的整数 K ?

输入格式

第一行包含三个整数 N,M 和 K.

之后 N 行每行包含 M 个整数, 代表矩阵 A.

输出格式

一个整数代表答案。

样例输入

  1. 3 4 10
  2. 1 2 3 4
  3. 5 6 7 8
  4. 9 10 11 12

样例输出

19

参考代码:

(暴力法只能通过30%测试)

  1. N,M,K=map(int,input().split())
  2. a=[[0] for i in range(N)]
  3. a.insert(0,[0]*(M+1))
  4. for i in range(1,N+1): #从a[1]1[1]开始读矩阵
  5. a[i].extend(map(int,input().split()))
  6. ans=0
  7. for i1 in range(1,N+1):
  8. for i2 in range(i1,N+1):
  9. for j1 in range(1,M+1):
  10. for j2 in range(j1,M+1):
  11. sum=0
  12. for i in range(i1,i2+1):
  13. for j in range(j1,j2+1):
  14. sum+=a[i][j]
  15. if sum<=K: #当和不超过 K 时,ans + 1
  16. ans+=1
  17. print(ans)

 方法二:前缀和、尺取法

  1. n,m,k=map(int,input().split())
  2. a=[[0] for i in range(n)] # 0 行全为 0
  3. a.insert(0,[0]*(m+1)) #insert将[0]*(m+1)添加到a[0]
  4. for i in range(1,n+1):
  5. a[i].extend(map(int,input().split())) #读入每一行矩阵
  6. s=[[0]*(m+1) for i in range(n+1)] #创建 n 行 m 列二维矩阵
  7. for i in range(n+1):
  8. for j in range(m+1):
  9. s[i][j]=s[i-1][j]+a[i][j] #求第 j 列第 i 行上数字的前缀和
  10. ans=0
  11. for i1 in range(1,n+1): #暴力遍历行
  12. for i2 in range(i1,n+1): #暴力遍历行
  13. j1=1
  14. z=0
  15. for j2 in range(1,m+1): #j2 列上,i1~i2的区间和。累加得到二维区间和
  16. z+=s[i2][j2]-s[i1-1][j2]
  17. while z>k: #若区间和 > k,移动指针 j1
  18. z-=s[i2][j1]-s[i1-1][j1] #后面指针前移
  19. j1+=1
  20. ans+=j2-j1+1 #若区间和小于 k
  21. print(ans)

        矩阵的行子区间仍用暴力二重遍历

        只把列区间和用尺取法优化 

1:Python insert()方法

描述

insert() 函数用于将指定对象插入列表的指定位置。

语法

insert()方法语法:

list.insert(index, obj)

参数

  • index -- 对象 obj 需要插入的索引位置。
  • obj -- 要插入列表中的对象。

返回值

该方法没有返回值,但会在列表指定位置插入对象。

2:Python  extend()方法

描述

extend() 函数用于在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)。

语法

extend()方法语法:

list.extend(seq)

参数

  • seq -- 元素列表。

返回值

该方法没有返回值,但会在已存在的列表中添加新的列表内容。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/800346
推荐阅读
相关标签
  

闽ICP备14008679号