题目描述:
给定一个n*m矩阵A,矩阵中每个元素Aij为一个16进制数。寻找一条从左上角到右下角的路径,每次只能向右或者向下移动,使得路径上所有数字之积在16进制下的后缀0最少。(乘积包含开始和结束位置)
输入输出例子忘记保存了。遗憾之处,在计算0的时候忘记写break语句了。还要多练习。
Python实现(深度优先搜索dfs):
# Bytedance AI Camp 2018 -编程题1-(北京时间)05月26日 09时30分-05月26日 12时00分 # 解题思路 深度优先搜索,用栈实现,符合的路径一直入栈,直到找到出口,计算后缀0的个数,并更新数据,然后出栈 # 找不到可走位置,则出栈 # @Time :2018/5/26 # @Author :LiuYinxing def findPath(maps, n, m): if n < 2 or n > 1000 or m < 2 or m > 1000: return None for i in range(n): # 把16进制的数字转换成10进制 for j in range(m): maps[i][j] = int(maps[i][j], 16) path = [[1] * m for _ in range(n)] # 标记路径是否已经走过 st, path[0][0] = [[0, 0, -1]], 0 # 初始化栈,并标记0 0 位置已经走过 findp, min0 = [], float('inf') # 记录路径和最小后缀零的个数 while st: i, j, di = st[-1][0], st[-1][1], st[-1][2] # 获取栈顶原始 i1, j1, find = -1, -1, 0 # 下一个可能扩展的结点 while di < 2 and find == 0: di += 1 if di == 0: # 向右 i1, j1 = i, j + 1 elif di == 1: # 向下 i1, j1 = i + 1, j if -1 < i1 < n and -1 < j1 < m and path[i1][j1] == 1: find = 1 # 找到 if find == 1: # 找到进栈 st[-1][2] = di # 当前栈顶的一个方向 进入下一个可走的方格 st.append([i1, j1, -1]) # 入栈 path[i1][j1] = 0 # 此位置已经走过 if st[-1][0] == n - 1 and st[-1][1] == m - 1: # 找到右下角 product, count0, tmppath = 1, 0, '' # 记录本次的乘积,后缀0的个数,和路径(字符串) for v in st: product *= maps[v[0]][v[1]] # 获取乘积 if v[2] == 0: tmppath += '>' elif v[2] == 1: tmppath += 'V' product = hex(product) for i in range(len(product) - 1, 0, -1): # 从倒数第一个字符开始计算 if product[i] == '0': count0 += 1 # 统计后缀0的个数 else: break # 遇到不是0的字符串结束 if count0 < min0: min0, findp = count0, [tmppath] # 找到后缀0更少的,更新min0, 清空findp并添加新的值 elif count0 == min0: findp.append(tmppath) # 如果找到后缀0个数一样的,追加到findp里面 path[st[-1][0]][st[-1][1]] = 1 # 出栈 st.pop() else: path[st[-1][0]][st[-1][1]] = 1 # 出栈 st.pop() print(min0) print(sorted(findp)[0]) # 对路径排序,输出第一个 if __name__ == '__main__': # n, m = map(int, input().split()) # maps = [] # for case in range(n): # caption = list(map(str, input().split())) # arr.append(caption) n, m = 3, 3 maps = [['3', '2', '8'], ['c', '8', '8'], ['2', 'a', 'f']] findPath(maps, n, m)
发现问题请评论指正哦。