华为5.7机考-最小代价相遇的路径规划Java题解

题目内容

输入描述

输出描述

示例:

输入:

复制代码
2
1 2
2 1

输出:

复制代码
3

思路:

Dijkstra 算法实现

dijkstra(int sx, int sy, int[][] dirs) 方法:

  • 参数:起点坐标 (sx, sy) 和允许的移动方向

  • 初始化

    • dist 数组存储到每个点的最短距离,初始为 INF

    • 起点的距离初始化为该点的值 grid[sx][sy]

  • 优先队列:存储待处理的节点,按距离从小到大排序

  • 处理队列

    • 取出当前距离最小的点

    • 跳过已经处理过的点(距离大于当前存储的距离)

    • 检查所有允许方向的邻居

    • 如果找到更短路径,更新距离并加入队列

主逻辑

  • 从起点 (0,0) 和终点 (n-1,n-1) 分别执行 Dijkstra 算法

    • dirs1: 只允许向右和向下移动

    • dirs2: 只允许向左和向上移动

  • 遍历所有可能的中间点:

    • 检查当前点是否可达(距离不为 INF)

    • 检查四个方向的邻居是否可达

    • 计算路径的最大值(从起点到当前点,和从邻居到终点的最大值)

    • 更新全局最小值 ans

  1. Dijkstra 算法的变种

    • 传统 Dijkstra 用于图的最短路径,这里应用于网格

    • 允许的移动方向由参数控制,可以灵活调整

  2. 双向搜索思想

    • 从起点和终点分别搜索,提高效率

    • 在中间点汇合时计算最终结果

  3. 优先队列的使用

    • Java 的 PriorityQueue 默认是最小堆

    • 通过 Comparator.comparingLong(a -> a[0]) 确保按距离排序

  4. 边界条件处理

    • 检查坐标是否越界

    • 跳过值为 0 的障碍点

    • 处理不可达情况(距离为 INF)

    import java.util.;
    import java.io.
    ;

    public class GridShortestPath {
    static final long INF = (long)1e18;
    static int n;
    static int[][] grid;

    复制代码
     public static void main(String[] args) throws IOException {
         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
         n = Integer.parseInt(br.readLine());
         grid = new int[n][n];
         
         // 读取网格数据
         for (int i = 0; i < n; i++) {
             String[] row = br.readLine().split(" ");
             for (int j = 0; j < n; j++) {
                 grid[i][j] = Integer.parseInt(row[j]);
             }
         }
         
         // 定义两个方向的移动
         int[][] dirs1 = {{0, 1}, {1, 0}};  // 向右和向下
         int[][] dirs2 = {{-1, 0}, {0, -1}}; // 向左和向上
         
         // 从起点(0,0)开始计算最短路径
         long[][] dist1 = dijkstra(0, 0, dirs1);
         // 从终点(n-1,n-1)开始计算最短路径
         long[][] dist2 = dijkstra(n-1, n-1, dirs2);
         
         long ans = INF;
         // 遍历所有可能的中间点
         for (int i = 0; i < n; i++) {
             for (int j = 0; j < n; j++) {
                 if (grid[i][j] == 0 || dist1[i][j] == INF) continue;
                 
                 // 检查四个方向的邻居
                 int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
                 for (int[] dir : directions) {
                     int ni = i + dir[0];
                     int nj = j + dir[1];
                     
                     if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;
                     if (grid[ni][nj] == 0 || dist2[ni][nj] == INF) continue;
                     
                     // 计算当前路径的最大值
                     long currentMax = Math.max(dist1[i][j], dist2[ni][nj]);
                     ans = Math.min(ans, currentMax);
                 }
             }
         }
         
         System.out.println(ans == INF ? -1 : ans);
     }
     
     // Dijkstra算法实现
     static long[][] dijkstra(int sx, int sy, int[][] dirs) {
         long[][] dist = new long[n][n];
         for (int i = 0; i < n; i++) {
             Arrays.fill(dist[i], INF);
         }
         dist[sx][sy] = grid[sx][sy];
         
         // 优先队列,按距离排序
         PriorityQueue<long[]> pq = new PriorityQueue<>(Comparator.comparingLong(a -> a[0]));
         pq.add(new long[]{dist[sx][sy], sx, sy});
         
         while (!pq.isEmpty()) {
             long[] current = pq.poll();
             long d = current[0];
             int x = (int)current[1];
             int y = (int)current[2];
             
             if (d > dist[x][y]) continue;
             
             for (int[] dir : dirs) {
                 int nx = x + dir[0];
                 int ny = y + dir[1];
                 
                 if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
                 if (grid[nx][ny] == 0) continue;
                 
                 long nd = d + grid[nx][ny];
                 if (nd < dist[nx][ny]) {
                     dist[nx][ny] = nd;
                     pq.add(new long[]{nd, nx, ny});
                 }
             }
         }
         
         return dist;
     }

    }

相关推荐
MATLAB代码顾问3 分钟前
混合粒子群-模拟退火算法(HPSO-SA)求解作业车间调度问题——附MATLAB代码
算法·matlab·模拟退火算法
Felven7 分钟前
C. Prefix Min and Suffix Max
算法
加农炮手Jinx7 分钟前
LeetCode 26. Remove Duplicates from Sorted Array 题解
算法·leetcode·力扣
加农炮手Jinx8 分钟前
LeetCode 88. Merge Sorted Array 题解
算法·leetcode·力扣
格林威8 分钟前
线阵工业相机:如何计算线阵相机的行频(Line Rate)?公式+实例
开发语言·人工智能·数码相机·算法·计算机视觉·工业相机·线阵相机
yueyue54311 分钟前
透过现象看本质:以fast_lio架构的整套算法的局部避障改为TEB算法为例深度探讨——如何成为一个合格的算法架构师?
算法·架构
梨花爱跨境11 分钟前
红人视频×A10算法:亚马逊转化率与流量闭环实战
算法
阿Y加油吧16 分钟前
二刷 LeetCode:75. 颜色分类 & 31. 下一个排列 复盘笔记
笔记·算法·leetcode
风筝在晴天搁浅17 分钟前
LeetCode 378.有序矩阵中第K小的元素
算法·矩阵
UnicornDev24 分钟前
【HarmonyOS 6】底部悬浮导航的迷你栏适配(API23)
华为·harmonyos·arkts·鸿蒙