【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【DP】2024D-园区参观路径【欧弟算法】全网注释最详细分类最全的华为OD真题题解

有LeetCode算法/华为OD考试扣扣交流群可加 948025485
可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳 od1441了解算法冲刺训练(备注【CSDN】否则不通过)

从2024年4月15号开始,OD机考全部配置为2024D卷
注意两个关键点:

  1. 会遇到C卷复用题。虽然可能存在幸存者偏差,但肯定还会有一大部分的旧题。
  2. 现在又支持做完题目之后倒回去改了。就是可以先做200的再做100的,然后可以反复提交。

在这里插入图片描述

题目描述与示例

题目描述

园区某部门举办了Family Day,邀请员工及其家属参加;将公司园区视为一个矩形,起始园区设置在左上角,终点园区设置在右下角;家属参观园区时,只能向右和向下园区前进;求从起始园区到终点园区会有多少条不同的参观路径

在这里插入图片描述

输入描述

第一行为园区长和宽;后面每一行表示该园区是否可以参观,0表示可以参观,1表示不能参观

1 <= 园区长, 园区宽 <= 100

输出描述

输出为不同的路径数量

示例

输入

3 3
0 0 0
0 1 0
0 0 0

输出

2

解题思路

注意,本题和LC63. 不同路径 II 完全一致,属于经典的二维dp路径问题。

代码

python

# 题目:【DP】2023C-园区参观路径
# 分值:200
# 作者:许老师-闭着眼睛学数理化
# 算法:DP
# 代码看不懂的地方,请直接在群上提问


# 输入长n、宽m
n, m = map(int, input().split())
# 构建网格
grid = list()
for _ in range(n):
    row = list(map(int, input().split()))
    grid.append(row)

# 设置二维数组 dp 用来储存到达每个位置时不同路径的数量
# dp[0][0] 表示从第 0 行第 0 列到达第 0 行第 0 列时不同路径的数量
# dp[0][i] 表示从第 0 行第 0 列到达第 0 行第 i 列时不同路径的数量
# dp[j][0] 表示从第 0 行第 0 列到达第 j 行第 0 列时不同路径的数量
# dp[i][j] 表示从第 0 行第 0 列到达第 i 行第 j 列时不同路径的数量
dp = [[0] * m for _ in range(n)]

# 初始化第一列的情况
for i in range(n):
    # 如果遇到障碍,则退出循环
    if grid[i][0] == 1:
        break
    # 否则记录到达点(i,0)的方法数为1种
    dp[i][0] = 1

# 初始化第一行的情况
for j in range(m):
    # 如果遇到障碍,则退出循环
    if grid[0][j] == 1:
        break
    # 否则记录到达点(0,j)的方法数为1种
    dp[0][j] = 1

# 双重循环执行dp过程
for i in range(1, n):
    for j in range(1, m):
        # 如果点(i,j)是障碍,则跳过
        if grid[i][j] == 1:
            continue
        # 否则,点(i,j)既可以从左边(i,j-1)也可以从上边(i-1,j)转移过来
        dp[i][j] = dp[i][j-1] + dp[i-1][j]

# 输出dp数组到达点(n-1,m-1)的方法数,即为达到右下角的方法数
print(dp[n-1][m-1])

java

import java.util.Scanner;  
  
public class Main {  
    public static void main(String[] args) {  
        Scanner scanner = new Scanner(System.in);  
        int n = scanner.nextInt();  
        int m = scanner.nextInt();  
        scanner.nextLine(); // Consume the rest of the line  
  
        int[][] grid = new int[n][m];  
        int[][] dp = new int[n][m];  
  
        for (int i = 0; i < n; ++i) {  
            String[] row = scanner.nextLine().split(" ");  
            for (int j = 0; j < m; ++j) {  
                grid[i][j] = Integer.parseInt(row[j]);  
            }  
        }  
  
        for (int i = 0; i < n; ++i) {  
            if (grid[i][0] == 1) break;  
            dp[i][0] = 1;  
        }  
  
        for (int j = 0; j < m; ++j) {  
            if (grid[0][j] == 1) break;  
            dp[0][j] = 1;  
        }  
  
        for (int i = 1; i < n; ++i) {  
            for (int j = 1; j < m; ++j) {  
                if (grid[i][j] == 1) continue;  
                dp[i][j] = dp[i][j-1] + dp[i-1][j];  
            }  
        }  
  
        System.out.println(dp[n-1][m-1]);  
  
        scanner.close();  
    }  
}

cpp

#include <iostream>  
#include <vector>  
  
using namespace std;  
  
int main() {  
    int n, m;  
    cin >> n >> m;  
  
    vector<vector<int>> grid(n, vector<int>(m));  
    vector<vector<int>> dp(n, vector<int>(m, 0));  
  
    for (int i = 0; i < n; ++i) {  
        for (int j = 0; j < m; ++j) {  
            cin >> grid[i][j];  
        }  
    }  
  
    for (int i = 0; i < n; ++i) {  
        if (grid[i][0] == 1) break;  
        dp[i][0] = 1;  
    }  
  
    for (int j = 0; j < m; ++j) {  
        if (grid[0][j] == 1) break;  
        dp[0][j] = 1;  
    }  
  
    for (int i = 1; i < n; ++i) {  
        for (int j = 1; j < m; ++j) {  
            if (grid[i][j] == 1) continue;  
            dp[i][j] = dp[i][j-1] + dp[i-1][j];  
        }  
    }  
  
    cout << dp[n-1][m-1] << endl;  
  
    return 0;  
}

时空复杂度

时间复杂度:O(NM)。dp过程中,双重循环所需时间复杂度

空间复杂度:O(NM)。二维dp数组所占空间。


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务300+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值