2023华为OD机试 (B卷)|200分 最小传输时延Ⅱ(Java JavaScript C++ Python)

该文描述了一个编程问题,涉及一个M*N的节点矩阵,每个节点可以向8个方向转发数据包,并有特定的时延规则。问题的目标是找出从左上角(0,0)到右下角(M-1,N-1)的最短时延路径。给定的Java、JavaScript、C++和Python代码实现了深度优先搜索(DFS)算法来解决这个问题。
摘要由CSDN通过智能技术生成

题目描述

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

输入描述

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

输出描述

最短时延值

用例

输入3 3
0 2 2
1 2 1
2 2 1
输出3
说明
输入3 3
2 2 2
2 2 2
2 2 2
输出4
说明(2+2+2-(3-1))

Java

import java.util.*;

public class Main {
    static int m, 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> res = new ArrayList<>(); // 存储所有到达终点的路径的延迟时间
        Set<Integer> path = new HashSet<>(); // 存储当前路径中已经访问过的位置
        path.add(0); // 将起点加入路径中
        dfs(0, 0, 0, Integer.MAX_VALUE, path, res); // 从起点开始遍历矩阵
        System.out.println(Collections.min(res)); // 输出所有到达终点的路径中的最小延迟时间
    }

    private static void dfs(int i, int j, int delay, int last, Set<Integer> path, List<Integer> res) {
        int cur = matrix[i][j]; // 当前位置的值
        boolean flag = cur == last; // 判断是否需要等待一秒
        if (i == m - 1 && j == n - 1) { // 到达终点
            delay += cur - (flag ? 1 : 0); // 更新延迟时间
            res.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 && !path.contains(pos)) { // 判断新的位置是否越界且是否已经访问过
                path.add(pos); // 将新的位置加入路径中
                dfs(new_i, new_j, delay + cur - (flag ? 1 : 0), cur, path, res); // 递归遍历新的位置
                path.remove(pos); // 将新的位置从路径中删除,回溯到上一步
            }
        }
    }
}

JavaScript

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

let m, n;
let matrix = [];
let offsets = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]];

function dfs(i, j, delay, last, path, res) {
  let cur = matrix[i][j];
  let flag = cur === last;
  if (i === m - 1 && j === n - 1) {
    delay += cur - (flag ? 1 : 0);
    res.push(delay);
    return;
  }
  for (let offset of offsets) {
    let new_i = i + offset[0];
    let new_j = j + offset[1];
    let pos = new_i * n + new_j;
    if (new_i >= 0 && new_i < m && new_j >= 0 && new_j < n && !path.has(pos)) {
      path.add(pos);
      dfs(new_i, new_j, delay + cur - (flag ? 1 : 0), cur, path, res);
      path.delete(pos);
    }
  }
}

rl.on('line', function (line) {
  if (!m) {
    [m, n] = line.split(' ').map(Number);
    matrix = Array(m).fill().map(() => Array(n).fill(0));
  } else {
    let row = matrix.length - m;
    matrix[row] = line.split(' ').map(Number);
    if (row === m - 1) {
      let res = [];
      let path = new Set();
      path.add(0);
      dfs(0, 0, 0, Infinity, path, res);
      console.log(Math.min(...res));
      rl.close();
    }
    m--;
  }
});

C++

#include <iostream>
#include <vector>
#include <unordered_set>
#include <climits>
#include <algorithm>

using namespace std;

int m, n; // 矩阵的行数和列数
vector<vector<int>> matrix; // 存储矩阵的二维向量
vector<vector<int>> offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; // 存储八个方向的偏移量

void dfs(int i, int j, int delay, int last, unordered_set<int>& path, vector<int>& res) {
    int cur = matrix[i][j]; // 当前位置的值
    bool flag = cur == last; // 判断是否需要等待一秒
    if (i == m - 1 && j == n - 1) { // 到达终点
        delay += cur - (flag ? 1 : 0); // 更新延迟时间
        res.push_back(delay); // 将当前的延迟时间加入结果向量
        return;
    }
    for (auto& 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 && !path.count(pos)) { // 判断新的位置是否越界且是否已经访问过
            path.insert(pos); // 将新的位置加入路径中
            dfs(new_i, new_j, delay + cur - (flag ? 1 : 0), cur, path, res); // 递归遍历新的位置
            path.erase(pos); // 将新的位置从路径中删除,回溯到上一步
        }
    }
}

int main() {
    cin >> m >> n; // 输入矩阵的行数和列数
    matrix.resize(m, vector<int>(n)); // 初始化矩阵的二维向量
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            cin >> matrix[i][j]; // 输入矩阵的每个元素
        }
    }
    vector<int> res; // 存储所有到达终点的路径的延迟时间
    unordered_set<int> path; // 存储当前路径中已经访问过的位置
    path.insert(0); // 将起点加入路径中
    dfs(0, 0, 0, INT_MAX, path, res); // 从起点开始遍历矩阵
    cout << *min_element(res.begin(), res.end()) << endl; // 输出所有到达终点的路径中的最小延迟时间
    return 0;
}

Python

m, n = map(int, input().split()) # 输入矩阵的行数和列数
matrix = [] # 存储矩阵的二维列表
for i in range(m):
    row = list(map(int, input().split())) # 输入矩阵的每个元素
    matrix.append(row)
offsets = [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, -1), (1, 1)] # 存储八个方向的偏移量

def dfs(i, j, delay, last, path, res):
    cur = matrix[i][j] # 当前位置的值
    flag = cur == last # 判断是否需要等待一秒
    if i == m - 1 and j == n - 1: # 到达终点
        delay += cur - (1 if flag else 0) # 更新延迟时间
        res.append(delay) # 将当前的延迟时间加入结果列表
        return
    for offset in offsets: # 遍历八个方向
        new_i = i + offset[0] # 新的行坐标
        new_j = j + offset[1] # 新的列坐标
        pos = new_i * n + new_j # 将二维坐标转换为一维坐标
        if 0 <= new_i < m and 0 <= new_j < n and pos not in path: # 判断新的位置是否越界且是否已经访问过
            path.add(pos) # 将新的位置加入路径中
            dfs(new_i, new_j, delay + cur - (1 if flag else 0), cur, path, res) # 递归遍历新的位置
            path.remove(pos) # 将新的位置从路径中删除,回溯到上一步

res = [] # 存储所有到达终点的路径的延迟时间
path = set([0]) # 存储当前路径中已经访问过的位置
dfs(0, 0, 0, float('inf'), path, res) # 从起点开始遍历矩阵
print(min(res)) # 输出所有到达终点的路径中的最小延迟时间

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值