华为OD机试算法:最小传输时延Ⅱ

题目描述

有M*N的节点矩阵,每个节点可以向8个方向(上、下、左、右及四个斜线方向)转发数据包,每个节点转发时会消耗固定时延,连续两个相同时延可以减少一个时延值(即当有K个相同时延的节点连续转发时可以减少K- 1个时延值),

求左上角(0,0)开始转发数据包到右下角(M-1,N- 1)并转发出的最短时延。

输入描述

第一行两个数字,M、N,接下来有M行,每行有N个数据,表示M* N的矩阵。

输出描述

最短时延值。

用例

题目解析

1.首先,我们需要创建一个二维数组dp,用于存储从左上角到每个位置的最短时延。dp[i][j]表示从左上角到位置(i, j)的最短时延。

2.然后,我们需要遍历输入矩阵,对于每个位置(i, j),计算从左上角到该位置的最短时延。我们可以从上方、左方和左上方的位置转移过来,取这三个位置中最短时延加当前位置的值作为dp[i][j]的值。

3.最后,返回dp数组右下角的值,即为最短时延。

JavaScript算法源码
const readline = require("readline");
const rl = readline.createInterface({ input: process.stdin });
const iter = rl[Symbol.asyncIterator]();

async function readLine() {
  return (await iter.next()).value;
}

(async function () {
  const [m, n] = (await readLine()).split(" ").map(Number);
  const matrix = [];
  const dist = new Array(m).fill(0).map(() => new Array(n).fill(Infinity));

  for (let i = 0; i < m; i++) {
    matrix.push((await readLine()).split(" ").map(Number));
  }

  console.log(spfa(matrix, dist, m, n));
})();

const offsets = [
  [-1, 0],
  [1, 0],
  [0, -1],
  [0, 1],
  [-1, -1],
  [-1, 1],
  [1, -1],
  [1, 1],
];

function spfa(matrix, dist, m, n) {
  const queue = [[0, 0]];
  dist[0][0] = matrix[0][0];

  while (queue.length > 0) {
    const [x, y] = queue.shift();

    for (let [offsetX, offsetY] of offsets) {
      const newX = x + offsetX;
      const newY = y + offsetY;

      if (newX >= 0 && newX < m && newY >= 0 && newY < n) {
        let newDist = dist[x][y] + matrix[newX][newY];

        if (matrix[newX][newY] === matrix[x][y] && matrix[x][y] >= 1) {
          newDist -= 1;
        }

        if (newDist < dist[newX][newY]) {
          dist[newX][newY] = newDist;
          queue.push([newX, newY]);
        }
      }
    }
  }

  return dist[m - 1][n - 1];
}

Java算法源码
import java.util.Scanner;

public class Main {
    // 地图矩阵
    static int[][] matrix;

    // 最短路径矩阵,即dist[i][j]记录的是坐标(i,j)到(0,0)的最短距离
    static int[][] dist;

    // 地图矩阵行数
    static int numRows;
    // 地图矩阵列数
    static int numCols;

    // 八个方向偏移量
    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 sc = new Scanner(System.in);

        numRows = sc.nextInt();
        numCols = sc.nextInt();

        matrix = new int[numRows][numCols];
        dist = new int[numRows][numCols];
        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j < numCols; j++) {
                matrix[i][j] = sc.nextInt();
                // 最短路径矩阵初始化,假设每个点到(0,0)距离无穷大
                dist[i][j] = Integer.MAX_VALUE;
            }
        }

        System.out.println(spfa());
    }

    public static int spfa() {
        int[] queue = new int[numRows * numCols];
        int front = 0, rear = 0;
        queue[rear++] = 0; // 起始点入队
        dist[0][0] = matrix[0][0];

        while (front != rear) {
            int currentIndex = queue[front++];
            int currentX = currentIndex / numCols;
            int currentY = currentIndex % numCols;

            for (int[] offset : offsets) {
                int newX = currentX + offset[0];
                int newY = currentY + offset[1];

                if (newX >= 0 && newX < numRows && newY >= 0 && newY < numCols) {
                    int newDist = dist[currentX][currentY] + matrix[newX][newY];

                    // 题目说:连续两个相同时延可以减少一个时延值
                    // 但是需要注意的是,应该不能产生负的时延值,比如前一个时延是0,当前时延也是0,则减少1个时延值,不应该变为-1
                    if (matrix[newX][newY] == matrix[currentX][currentY] && matrix[newX][newY] >= 1) {
                        newDist -= 1;
                    }

                    if (newDist < dist[newX][newY]) {
                        dist[newX][newY] = newDist;
                        queue[rear++] = newX * numCols + newY; // 新点入队
                    }
                }
            }
        }

        return dist[numRows - 1][numCols - 1];
    }
}

Python算法源码
import sys
from collections import deque

# 输入获取
m, n = map(int, input().split())
matrix = [list(map(int, input().split())) for i in range(m)]

# 最短距离矩阵
dist = [[sys.maxsize for _ in range(n)] for _ in range(m)]

# 八个方向的偏移量
offsets = ((-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, -1), (1, 1))

# 算法入口
def spfa():
    queue = deque()
    queue.append((0, 0))
    dist[0][0] = matrix[0][0]

    while queue:
        x, y = queue.popleft()

        for offsetX, offsetY in offsets:
            newX = x + offsetX
            newY = y + offsetY

            if m > newX >= 0 and n > newY >= 0:
                newDist = dist[x][y] + matrix[newX][newY]

                if matrix[newX][newY] == matrix[x][y] and matrix[newX][newY] >= 1:
                    newDist -= 1

                if newDist < dist[newX][newY]:
                    dist[newX][newY] = newDist
                    queue.append((newX, newY))

    return dist[m-1][n-1]

# 算法调用
print(spfa())

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务