【华为OD真题 Python】攀登者2

该博客讨论了如何使用Python解决华为在线开发者(OD)的一道题目,涉及攀登地图中山峰的问题。内容包括地图表示,登山体力消耗计算,以及如何确定登山者能安全返回地面的条件。通过示例输入和输出解释了问题的具体情况,并提供了实现代码来找出地图中所有可安全攀登的山峰数量。

题目描述

攀登者喜欢寻找各种地图,并且尝试攀登到最高的山峰。

地图表示为一维数组,数组的索引代表水平位置,数组的高度代表相对海拔高度。其中数组元素0代表地面。

例如[0,1,4,3,1,0,0,1,2,3,1,2,1,0], 代表如下图所示的地图,地图中有两个山脉位置分别为 1,2,3,4,5和8,9,10,11,12,13,最高峰高度分别为4,3。最高峰位置分别为3,10。
一个山脉可能有多座山峰(高度大于两边,或者在地图边界)。

           4 

         +---+ 
         |   | 
         |   | 3                       3 
         |   | 
         |   +---+                   ----- 
         |       |                   |   | 
       2 |       |                 2 |   |     2 
         |       |                   |   | 
     +---+       |               ----+   |   +---+ 
     |           |               |       |   |   | 
   1 |           | 1           1 |       | 1 |   | 1 
     |           |               |       |   |   | 
 +---+           +---+       +---+       +---+   +---+ 
 |                   |       |                       | 

0 | | 0 0 | | 0
| | | |
±–+ ±------+ ±–+

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
2. 登山时会消耗登山者的体力(整数),上山时,消耗相邻高度差两倍的体力,下坡时消耗相邻高度差一倍的体力,平地不消耗体力,登山者体力消耗到零时会有生命危险。
例如,上图所示的山峰,从索引0,走到索引1,高度差为1,需要消耗2X1 = 2 的体力,从索引2高度2走到高度4索引3需要消耗2X2 = 4 的体力。如果是从索引3走到索引4则消耗1X1的体力。
3. 登山者体力上限为999。
4. 登山时的起点和终点可以是地图中任何高度为0的地面例如上图中的0,6,7,14 都可以作为登山的起点和终点
攀登者想要评估一张地图内有多少座山峰可以进行攀登,且可以安全返回到地面,且无生命危险。

例如上图中的数组,有3个不同的山峰,登上位置在3的山可以从位置0或者位置6开始,从位置0登到山顶需要消耗体力1X2+1X2+2X2 = 8, 从山顶返回到地面0需要消耗体力 2X1 + 1X1 + 1X1 = 4 的体力,按照登山路线0->3->0需要消耗体力 12。攀登者至少需要12以上的体力(大于12)才能安全返回。

示例1

输入

[0,1,4,3,1,0,0,1,2,3,1,2,1,0],13

输出

3

说明

登山者只能够登上位置10和12的山峰,7->10->7, 14->12>14

示例2

输入

[1,4,3],999

输出

0

说明

没有合适的起点和终点

此为分隔符,请忽略

c K K K K K
K K K K
K K
x K K K K K K
K K K K K K K K
K K K K
x K K K K K K
K
v K K K K K K K K K
K K K K K
K K x K K K K
v K K K K
K K K
v K K K K
K K K K K K K K
K K K K K
x K K K K K K K K
K K K K K K K
K K K K K K K K
K K K K K K


实现代码

class Solution:
    def count_climbable(self, hill_map, strength):
        hills, real_hills, hills_pos = 0, 0, []
        n = len(hill_map)

        if hill_map[0] > hill_map[1]:
            hills += 1
            hills_pos.append(0)
        if hill_map[n - 2] < hill_map[n - 1]:
            hills += 1
            hills_pos.append(n - 1)

        for i in range(1, n - 1):
            if hill_map[i] > hill_map[i - 1] and hill_map[i] > hill_map[i + 1]:
                hills += 1
                hills_pos.append(i)

        for i in range(len(hills_pos)):
            power, needed = 0, 1
            for j in range(hills_pos[i] - 1, 0, -1):
                power += abs(hill_map[j] - hill_map[j - 1]) * 3
                if hill_map[j] == 0:
                    if power < strength:
                        real_hills += 1
                        needed = 0
                        break

            if needed == 0:
                continue

            power = 0
            for j in range(hills_pos[i] + 1, n):
                power += abs(hill_map[j - 1] - hill_map[j]) * 3
                if hill_map[j] == 0:
                    if power < strength:
                        real_hills += 1
                        break

        return real_hills

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值