这次百度算法工程师笔试题中的两个编程题目,第一个是排列组合问题,很闹心,耗费了不少时间,搞得第二道也没做完,平时还是要多练习呀。
题目: 爬山
内容:冬木市西边的园藏山是著名的旅游胜地。从空中俯瞰,园藏山可以看成一个n*m的矩阵,我们把行从上往下按1到n编号,把列从左到右按1到m编号,那么(i,j)就表示矩阵的第i行第j列的位置。我们用 hij, 表示位置(i,j)的海拔高度。
初始时,Saber在(sx, sy)这个位置, 她想前往更高的地方,每一次她可以选择向上、下、左、右其中一个方向走,但不能走出这个矩阵;同时,作为大不列颠的王,孤傲的Saber不愿意走到比她当前所在的位置海拔要低的位置,也就是说在移动的过程中,每一步她都只能向海拔不低于她当前所在的位置的那些位置移动。请你帮忙计算出她所能走到的最高高度。
Python 3 实现,
class Solution: # 回溯法, 用栈来实现
def findMax(self, n, m, ns, ms, maps):
st = [[ns, ms, -1]] # 开辟一个栈,并把初始化第一个值
cur_max = maps[ns][ms] # 当前最大值
path = [[1] * m for _ in range(n)] # 1 为可以走,0 为已经走过
path[ns][ms] = 0 # 标记第一个开始位置已经走过
while st: # 如果不为空
i, j, di, find = st[-1][0], st[-1][1], st[-1][2], 0
i1, j1 = -1, -1 # 记录下一步可走的坐标
while (di < 4 and find == 0):
di += 1
if di == 0: i1, j1 = i - 1, j # 向上走
elif di == 1: i1, j1 = i, j + 1 # 向右走
elif di == 2: i1, j1 = i + 1, j # 向下走
elif di == 3: i1, j1 = i, j - 1 # 向左走
if (i1 >= 0 and i1 < n) and (j1 >= 0 and j1 < m) and (path[i1][j1] == 1) and (maps[i1][j1] >= cur_max): find = 1
if find == 1:
st[-1][2] = di # 当前栈顶的一个方向 进入下一个可走的方格
st.append([i1, j1, -1]) # 入栈
cur_max = maps[i1][j1] # 更新最大值
path[i1][j1] = 0 # 已经走过了
else:
path[st[-1][0]][st[-1][1]] = 1 # 恢复可走的方格
st.pop() # 出栈
return cur_max
if __name__ == '__main__':
n, m = map(int, input().split()) # 输入矩阵的维度
ns, ms = map(int, input().split())
ns, ms = ns - 1, ms - 1 # 输入开始位置
maps = [] # 输入矩阵
for case in range(n):
tmp = list(map(int, input().split()))
maps.append(tmp)
# n, m = 4, 4 # 测试用例
# ns, ms = 2, 0
# maps = [[1, 1, 1, 2],
# [1, 2, 4, 3],
# [4, 2, 6, 6],
# [5, 1, 12, 10]]
solu = Solution()
print(solu.findMax(n, m, ns, ms, maps))