华为20190410研发笔试第三题:求两点之间的路径数

【题目描述】

  在一张NXM的地图上,每个点的海拔高度不同,从当前点只能访问上下左右四个点中还没有到达过的点,且下一步的选择的点的海拔高度必须高于当前的点;求从地图中的点A到点B的总的路径数量除以 1 0 9 10^9 109的余数。地图左上角坐标为(0,0),右下角的坐标为(N-1, M-1)。

【输入描述】

第一行输入两个整数N, M( 0 &lt; N ≤ 600 , 0 &lt; M ≤ 600 0&lt;N\leq600, 0&lt;M\leq600 0<N600,0<M600),用空格分开;接下来N行输入,每行M个整数用空格隔开,代表对应位置的海拔高度( 0 ≤ 海 拔 高 度 ≤ 360000 0\leq海拔高度\leq360000 0360000);最后一行输入四个整数X, Y, Z, W表示A的坐标为A(X,Y)和B的坐标B(Z, W)。输入保证A,B坐标不同且坐标合法。

【输出描述】

输出一个整数并换行,整数表示从A到B总的路径数量除以 1 0 9 10^9 109的余数。

【测试用例】

【输入】

4 5

0 1 0 0 0

0 2 3 0 0

0 0 4 5 0

0 0 7 6 0

0 1 3 2

【输出】

2

【解题思路】

本题适合采用递归的方式做,每次递归都有四个方向可供选择,即上下左右四个方向。当点移动到与目标点重合则返回1,否则当点移动到一个局部最高,即无法再继续移动且没有到达目标点,那么就返回0,每次递归返回上下左右四个方向之和,表示从该店到达目标点的路径数量

【代码】


def findtheway(A, x1, y1, x2, y2):
    # 如果到达指定坐标,返回1
    if x1 == x2 and y1 == y2:
        return 1
    # 如果到达一个点,无法再移动,且该点也不是目标点,返回0
    x_up = x1 - 1
    x_down = x1 + 1
    y_left = y1 - 1
    y_right = y1 + 1

    # 遇到边界的情况
    if x_up < 0:
        x_up = 0
    if x_down > len(A)-1:
        x_down = len(A)-1
    if y_left < 0:
        y_left = 0
    if y_right > len(A[0])-1:
        y_right = len(A[0])-1
	# 该点是局部最高,无法继续移动
    if A[x1][y1] >= max(A[x_down][y1], A[x_up][y1], A[x1][y_right], A[x1][y_left]):
        return 0

    up, down, left, right = 0, 0 ,0 ,0
    # 可以向左移动
    if y1-1 >= 0 and A[x1][y1] < A[x1][y1-1]:
        left = findtheway(A, x1, y1-1, x2, y2)
    # 可以向右移动
    if y1+1 <= len(A[0])-1 and  A[x1][y1] < A[x1][y1+1]:
        right = findtheway(A, x1, y1+1, x2, y2)
    # 可以向上移动
    if x1-1 >= 0 and A[x1][y1] < A[x1-1][y1]:
        up = findtheway(A, x1-1, y1, x2, y2)
    # 可以向下移动
    if x1+1 <= len(A)-1 and A[x1][y1] < A[x1+1][y1]:
        down = findtheway(A, x1+1, y1, x2, y2)

    return up+down+left+right

if __name__ == '__main__':
    N, M = 4, 5
    A = [[0, 1, 0, 0, 0],
         [0, 2, 3, 0, 0],
         [0, 0, 4, 5, 0],
         [0, 0, 7, 6, 0]]

    x1, y1 = 0, 1
    x2, y2 = 3, 2

    print(findtheway(A, x1, y1, x2, y2) % 10**9)
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值