青蛙过河 问题

蓝桥杯 | 青蛙过河 问题 | 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 的跳跃能力。

  1. 官方题解

在这里插入图片描述
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)
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值