题目背景
一个机器人位于一个 n x m 网格的左上角 机器人每次只能向下或者向右移动一步。它试图达到网格的右下角
题目描述
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径? 网格中的障碍物和空位置分别用 1 和 0 来表示。
输入格式
第一行两个数n,m,
第二行到n+1行为网格
输出格式
路径总数
输入输出样例
输入
3 3
000
010
000
输出
2
说明/提示
1 <= m, n <= 100
网格里只有 0 或 1
另: 对于样例,3x3 网格的正中间有一个障碍物。 从左上角到右下角一共有 2 条不同的路径:
向右 -> 向右 -> 向下 -> 向下
向下 -> 向下 -> 向右 -> 向右
解题思路:
这题跟不同路径 I的区别就是加了障碍,不过也是简单题,我们只要标记障碍的位置,用st数组进行标记,记住,这题输入的话要用char,如果我们用int,当我们输入数字0和1时,因为之间没有空格,计算机是不知道数字怎么分开的,所以用char读入。首先我们定义dp[i][j]表示为机器人从左上角走到(i,j)这个点的走法总数,然后因为机器人每次只能向下或者向右移动一步,所以不难想到关系表达式为:
dp[i][j] = dp[i-1][j]+dp[i][j-1];
当机器人遇到障碍,dp[i][j] = 0;
然后我们想想如何初始化,因为机器人从左上角一直往左走,或者一直往下走,只有一种走法,然后如果这路径有障碍,后面的路就无法走了,当然,如果最开始左上角的位置就有障碍,那就根本走不到右下角,故初始化代码如下:
if (st[0][0]) {cout << "0" << endl;return 0;}elsedp[0][0] = 1;
for (int i = 1; i < n; i++) {if (st[i][0])dp[i][0] = 0;elsedp[i][0] = dp[i - 1][0];}
for (int i = 1; i < m; i++) {if (st[0][i])dp[0][i] = 0;elsedp[0][i] = dp[0][i - 1];}
ac代码如下:
#include <iostream>
using namespace std;
const int N = 110;
char g[N][N];
bool st[N][N];
int dp[N][N];int main() {int n, m;cin >> n >> m;for (int i = 0; i < n; i++)for (int j = 0; j < m; j++) {cin >> g[i][j];if (g[i][j] == '1')st[i][j] = true;}if (st[0][0]) {cout << "0" << endl;return 0;}elsedp[0][0] = 1;for (int i = 1; i < n; i++) {if (st[i][0])dp[i][0] = 0;elsedp[i][0] = dp[i - 1][0];}for (int i = 1; i < m; i++) {if (st[0][i])dp[0][i] = 0;elsedp[0][i] = dp[0][i - 1];}for (int i = 1; i < n; i++)for (int j = 1; j < m; j++) {if (st[i][j])dp[i][j] = 0;elsedp[i][j] = dp[i - 1][j] + dp[i][j - 1];}cout << dp[n - 1][m - 1] << endl;return 0;
}