蓝桥杯 | 青蛙过河 问题 | python
问题描述
小青蛙住在一条河边, 它想到河对岸的学校去学习。小青蛙打算经过河里的石头跳到对岸。
河里的石头排成了一条直线, 小青蛙每次跳跃必须落在一块石头或者岸上。 不过, 每块石头有一个高度, 每次小青蛙从一块石头起跳,这块石头的高度就会下降 1 , 当石头的高度下降到 0 时小青蛙不能再跳到这块石头上(某次跳跃后使石头高度下降到 0 是允许的)。
小青蛙一共需要去学校上 x 天课, 所以它需要往返 2x 次。当小青蛙具有一个跳跃能力 y 时, 它能跳不超过 y 的距离。
请问小青蛙的跳跃能力至少是多少才能用这些石头上完 x 次课。
输入格式
输入的第一行包含两个整数 n,x, 分别表示河的宽度和小青蛙需要去学校的天数。请注意 2x 才是实际过河的次数。
第二行包含 n−1 个非负整数 H1,H2,…,Hn-1,其中 Hi>0 表示在河中与小青蛙的家相距 i 的地方有一块高度为 Hi 的石头,Hi =0 表示这个位置没有石头。
输出格式
输出一行, 包含一个整数, 表示小青蛙需要的最低跳跃能力。
样例输入
5 1
1 0 1 0
样例输出
4
样例说明
由于只有两块高度为 1 的石头,所以往返只能各用一块。第 1 块石头和对岸的距离为 4,如果小青蛙的跳跃能力为 3则无法满足要求。所以小青蛙最少需要 4 的跳跃能力。
- 官方题解
Pre_Sum差分数组:
python代码:
import os
import sys
# 请在此输入您的代码
n,x=list(map(int,input().split())) # 河的宽度和小青蛙需要去学校的天数,2x才是实际过河的次数
# H=[0,*list(map(int,input().split()))] # 下标从1开始,石头高度,H[0]=0
templ=list(map(int,input().split()))
H=[0]+templ
Pre_Sum=[0]*n # 差分数组,Pre_Sum[0]=0
for i in range(1,n): # 预处理前缀和,一共n-1块石头,1到n-1
Pre_Sum[i]=Pre_Sum[i-1]+H[i] # 由Pre_Sum知道指定区间范围内高度的累加
# 判定能力为y时,是否合法
def check(y):
# 暴力枚举所有长度为y的区间
for left in range(1,n-y+1): # 区间左端点从1取到n-y
right=left+y-1 # 为什么要-1?
if Pre_Sum[right]-Pre_Sum[left-1]<2*x:
return False
return True # “所有”区间长度等于y的区间,石头高度之和大于等于2x
# 二分查找
left,right=1,n # 初始左右端点
ans=-1
while left<=right:
mid=(left+right)//2
if check(mid): # 跳跃能力取mid可行
ans=mid
right=mid-1 # 再检查是否可以更小
else:
left=mid+1
print(ans)