当前位置:   article > 正文

【二分与前缀和】python例题详解

【二分与前缀和】python例题详解

文章目录

1、数的范围

2、数的三次方根

3、前缀和

4、子矩阵的和

5、机器人跳跃问题

1、数的范围

题目
给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。对于每个查询,返回一个元素 k的起始位置和终止位置(位置从 00 开始计数)。如果数组中不存在该元素,则返回 -1 -1
输入格式
第一行包含整数 n 和 q,表示数组长度和询问个数。第二行包含 n 个整数(均在 1∼100001∼10000 范围内),表示完整数组。接下来 q 行,每行包含一个整数 k,表示一个询问元素。
输出格式
共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。如果数组中不存在该元素,则返回 -1 -1

  1. n,m=map(int,input().split())
  2. a=list(map(int,input().split()))
  3. for i in range(m):
  4. b=int(input())
  5. l,r=0,n-1
  6. while l<r:
  7. zz=(l+r)//2
  8. if b<=a[zz]:
  9. r=zz
  10. else: l=zz+1
  11. if a[l]==b:
  12. print(l,end=' ')
  13. else :
  14. print(-1,end=' ')
  15. l,r=0,n-1
  16. while l<r:
  17. zz=(l+r+1)>>1
  18. if b>=a[zz]:
  19. l=zz
  20. else: r=zz-1
  21. if a[l]==b:
  22. print(l)
  23. else:print(-1)

2、数的三次方根

题目
给定一个浮点数 n,求它的三次方根。
输入格式
共一行,包含一个浮点数 n。
输出格式
共一行,包含一个浮点数,表示问题的解。注意,结果保留 66 位小数。

  1. l,r=-10000,10000
  2. n=float(input())
  3. while r>l+10**-8:
  4. mid=(l+r)/2
  5. if mid**3<=n:
  6. l=mid
  7. else: r=mid
  8. print("%.6f"%r)

3、前缀和

题目
输入一个长度为 n 的整数序列。接下来再输入 m 个询问,每个询问输入一对 l,r。对于每个询问,输出原序列中从第 l个数到第 r 个数的和。
输入格式
第一行包含两个整数 n和 m。第二行包含 n 个整数,表示整数数列。接下来 m行,每行包含两个整数 l 和 r,表示一个询问的区间范围。
输出格式
共 m行,每行输出一个询问的结果。

  1. n,m=map(int,input().split())
  2. a=list(map(int,input().split()))
  3. for i in range(1,n):
  4. a[i]+=a[i-1]
  5. while m:
  6. l,r=map(int,input().split())
  7. if l==1:
  8. print(a[r-1])
  9. else:print(a[r-1]-a[l-2])
  10. m-=1

4、子矩阵的和

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

  1. n,m,q=map(int,input().split())
  2. mt=[[0 for _ in range(m+1)]for __ in range(n+1)]
  3. sm=[[0 for _ in range(m+1)]for __ in range(n+1)]
  4. for i in range(1,n+1):
  5. mt[i][1:]=list(map(int,input().split()))
  6. sm[0][0]=mt[0][0]
  7. for i in range(1,n+1):
  8. for j in range(1,m+1):
  9. sm[i][j]=sm[i][j-1]+sm[i-1][j]+mt[i][j]-sm[i-1][j-1]
  10. for i in range(q):
  11. x1,y1,x2,y2=map(int,input().split())
  12. print(sm[x2][y2]-sm[x2][y1-1]-sm[x1-1][y2]+sm[x1-1][y1-1])

5、机器人跳跃问题

题目
机器人正在玩一个古老的基于 DOS 的游戏。游戏中有 N+1 座建筑——从 00 到 N编号,从左到右排列。编号为 00 的建筑高度为 00 个单位,编号为 i的建筑高度为 H(i)个单位。起初,机器人在编号为 00 的建筑处。每一步,它跳到下一个(右边)建筑。假设机器人在第 k个建筑,且它现在的能量值是 E,下一步它将跳到第 k+1个建筑。如果 H(k+1)>E,那么机器人就失去 H(k+1)−E 的能量值,否则它将得到 E−H(k+1)的能量值。游戏目标是到达第 N个建筑,在这个过程中能量值不能为负数个单位。现在的问题是机器人至少以多少能量值开始游戏,才可以保证成功完成游戏?
输入格式
第一行输入整数 N。第二行是 N个空格分隔的整数,H(1),H(2),…,H(N)代表建筑物的高度。
输出格式
输出一个整数,表示所需的最少单位的初始能量值上取整后的结果。

  1. n = int(input())
  2. #l,r = 0,10**5+10
  3. h = list(map(int,input().split()))
  4. l,r = 0,max(h)
  5. def check(x):
  6. for i in range(n):
  7. x+= x - h[i]
  8. if x < 0:
  9. return False
  10. return True
  11. while l < r:
  12. mid = l + r >> 1
  13. if check(mid):
  14. r = mid
  15. else:
  16. l = mid + 1
  17. print(l)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/470448
推荐阅读
相关标签
  

闽ICP备14008679号