📜  门| GATE-CS-2014-(Set-3)|问题16(1)

📅  最后修改于: 2023-12-03 15:12:42.426000             🧑  作者: Mango

门 | GATE-CS-2014-(Set-3)|问题16

这是一道GATE-CS-2014中的问题,主要涉及图形学和计算几何的知识,难度适中。下面将对题目、解题思路和代码进行详细介绍。

题目描述

有一个N×N的网格,其中一些网格被标记为“障碍物”。一个机器人从网格的左上角出发,需要到达网格的右下角。机器人只能向右或向下移动,并且不得进入任何已标记为“障碍物”的网格。请问机器人到达右下角有多少种不同的路径?

请实现下面的函数来求解问题:

def num_paths(n: int, m: int, obstacles: List[Tuple[int, int]]) -> int:
    pass

其中,n和m表示网格的行数和列数,obstacles是一个列表,其中每个元素都是包含两个整数的元组,表示障碍物所在的行和列。函数应该返回机器人从左上角到达右下角的所有不同路径的数量。

解题思路

本题实际上是一道简单的动态规划问题。我们可以定义一个二维数组dp,其中dp[i][j]表示从左上角出发到达位置(i,j)的不同路径数。由于机器人只能向右或向下移动,因此到达(i,j)只可能是从(i-1,j)或者(i,j-1)两个位置转移而来。即:

dp[i][j] = dp[i-1][j] + dp[i][j-1]

但是,如果位置(i,j)是一个障碍物的话,那么机器人无法到达该位置,因此dp[i][j]应该为0。

最终的结果即为dp[n-1][m-1],表示从左上角到达右下角的不同路径数。

代码实现

下面给出完整的Python代码实现:

from typing import List, Tuple

def num_paths(n: int, m: int, obstacles: List[Tuple[int, int]]) -> int:
    # 初始化dp数组
    dp = [[0] * m for _ in range(n)]
    
    # 初始化第一行和第一列
    for j in range(m):
        if (0, j) not in obstacles:
            dp[0][j] = 1
            
    for i in range(n):
        if (i, 0) not in obstacles:
            dp[i][0] = 1
            
    # 计算其余位置的路径数
    for i in range(1, n):
        for j in range(1, m):
            if (i, j) not in obstacles:
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
                
    return dp[n-1][m-1]

代码中,我们使用了列表推导式和嵌套循环来初始化dp数组和计算路径数。时间复杂度为O(nm),空间复杂度也为O(nm)。可以通过本题目。