
目录
- 专栏导读
 - 一、题目描述
 - 二、输入描述
 - 三、输出描述
 - 四、解题思路
 - 五、Java算法源码
 - 六、效果展示
 - 1、输入
 - 2、输出
 - 3、说明
 
华为OD机试 2023B卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述
有M*N的节点矩阵,每个节点可以向8个方向(上下左右及四个斜线防线)转发数据包,每个节点转发时会消耗固定时延,连续两个相同时延可以减少一个时延值(即当有K个相同时延的节点连续转发时可以减少K-1个时延值),求左上角(0,0)开始转发数据包到右下角(M-1,N-1)并转发出的最短时延。
二、输入描述
第一行两个数字,M,N,接下来有M行,每行有N个数据,表示M*N的矩阵。
三、输出描述
最短时延值。
四、解题思路
- 第一行输入矩阵的行数M和矩阵的列数N;
 - 接下来有M行,每行有N个数据,表示M*N的矩阵;
 - 定义矩阵的二维数组,并将输入值加入到二维数组;
 - 定义集合delayList,存储所有到达终点的路径的延迟时间;
 - 定义集合pathSet,存储当前路径中已经访问过的位置;
 - 将起点加入路径中;
 - 从起点开始遍历矩阵; 
  
- 判断是否到达终点;
 - 更新延迟时间;
 - 将当前的延迟时间加入结果列表;
 - 遍历八个方向;
 - 判断新的位置是否越界且是否已经访问过;
 - 将新的位置加入路径中;
 - 递归遍历新的位置;
 - 将新的位置从路径中删除,回溯到上一步;
 
 - 输出所有到达终点的路径中的最小延迟时间。
 
五、Java算法源码
package com.guor.od;
import java.util.*;
import java.util.regex.Pattern;
public class OdTest {
    // 矩阵的行数
    static int M;
    // 矩阵的列数
    static int N;
    // 存储矩阵的二维数组
    static int[][] matrix;
    static int[][] offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; // 存储八个方向的偏移量
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 输入矩阵的行数
        M = scanner.nextInt();
        // 输入矩阵的列数
        N = scanner.nextInt();
        // 初始化矩阵的二维数组
        matrix = new int[M][N];
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < N; j++) {
                // 输入矩阵的每个元素
                matrix[i][j] = scanner.nextInt();
            }
        }
        // 存储所有到达终点的路径的延迟时间
        List<Integer> delayList = new ArrayList<>();
        // 存储当前路径中已经访问过的位置
        Set<Integer> pathSet = new HashSet<>();
        // 将起点加入路径中
        pathSet.add(0);
        // 从起点开始遍历矩阵
        dfs(0, 0, 0, Integer.MAX_VALUE, pathSet, delayList);
        // 输出所有到达终点的路径中的最小延迟时间
        System.out.println(Collections.min(delayList));
    }
    private static void dfs(int i, int j, int delay, int last, Set<Integer> pathSet, List<Integer> delayList) {
        // 当前位置的值
        int cur = matrix[i][j];
        // 判断是否需要等待一秒
        boolean flag = cur == last;
        // 到达终点
        if (i == M - 1 && j == N - 1) {
            // 更新延迟时间
            delay += cur - (flag ? 1 : 0);
            // 将当前的延迟时间加入结果列表
            delayList.add(delay);
            return;
        }
        // 遍历八个方向
        for (int[] offset : offsets) {
            // 新的行坐标
            int new_i = i + offset[0];
            // 新的列坐标
            int new_j = j + offset[1];
            // 将二维坐标转换为一维坐标
            int pos = new_i * N + new_j;
            // 判断新的位置是否越界且是否已经访问过
            if (new_i >= 0 && new_i < M && new_j >= 0 && new_j < N && !pathSet.contains(pos)) {
                // 将新的位置加入路径中
                pathSet.add(pos);
                // 递归遍历新的位置
                dfs(new_i, new_j, delay + cur - (flag ? 1 : 0), cur, pathSet, delayList);
                // 将新的位置从路径中删除,回溯到上一步
                pathSet.remove(pos);
            }
        }
    }
}
 
六、效果展示
1、输入
3 3
 2 2 2
 2 2 2
 2 2 2
2、输出
4
3、说明
(2+2+2-(3-1))

🏆下一篇:华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。




















