2018 Bytedance AI Camp 编程题1

题目描述:

给定一个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)

发现问题请评论指正哦。

猜你喜欢

转载自blog.csdn.net/xx_123_1_rj/article/details/80461856