华为OD机试 - 基站维护工程师数 - 动态规划(Python/JS/C/C++ 2024 E卷 200分)

news2024/10/5 23:17:30

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

小王是一名基站维护工程师,负责某区域的基站维护。某地方有 n 个基站 (1 < n < 10),已知各基站之间的距离 s (0 <= s < 500),并且基站 x 到基站 y 的距离,与基站 y 到基站 x 的距离并不一定会相同。

小王从基站 1 出发,途经每个基站 1 次,然后返回基站 1。需要请你为他选择一条距离最短的路径。

二、输入描述

站点数 n 和各站点之间的距离 (均为整数)。

三、输出描述

最短路径的数值。

四、测试用例

测试用例1:

1、输入

3
0 2 1
1 0 2
2 1 0

2、输出

3

3、说明

测试用例2:

1、输入

4
0 10 15 20
10 0 35 25
15 35 0 30
20 25 30 0

2、输出

80

3、说明

路径 1 → 2 → 4 → 3 → 1,总距离为10 + 25 + 30 + 15 = 80。

五、解题思路

该问题是典型的旅行商问题(Traveling Salesman Problem, TSP),其中小王需要从基站1出发,经过每个基站一次后返回基站1。由于基站数量 n 较小(1 < n < 10),可以使用动态规划(Dynamic Programming, DP)结合位掩码(Bitmasking)来高效地解决。

  1. 距离矩阵(二维数组):
    • 使用二维数组 s[n][n] 存储各基站之间的距离。
    • 由于距离不对称,即 s[i][j] 不一定等于 s[j][i],所以需要单独存储。
  2. 动态规划数组(二维数组):
    • 使用 dp[mask][i] 表示访问过的基站集合为 mask,且最后访问的基站是 i 的最短路径长度。
    • mask 使用位掩码表示,其中第 k 位为1表示第 k 个基站已被访问。
  3. 算法流程:
    • 初始化 dp 数组,将起点基站1(索引0)的状态设为0。
    • 遍历所有可能的基站访问状态,通过动态规划逐步更新每个状态下的最短路径长度。
    • 遍历所有可能的结束基站,计算返回起点的最短路径,并取最小值作为结果。

六、Python算法源码

import sys

def main():
    # 读取所有输入
    input = sys.stdin.read().split()
    index = 0
    # 读取基站数量
    n = int(input[index])
    index += 1
    # 初始化距离矩阵
    s = []
    for i in range(n):
        row = []
        for j in range(n):
            row.append(int(input[index]))
            index += 1
        s.append(row)
    
    # 全部基站的状态,使用位掩码表示
    FULL_MASK = (1 << n) - 1
    # 初始化动态规划数组,dp[mask][i] 表示访问过mask状态,最后访问的基站是i的最小距离
    dp = [[float('inf')] * n for _ in range(1 << n)]
    # 起点是基站1,对应索引0,访问了基站1的状态
    dp[1 << 0][0] = 0
    
    # 遍历所有可能的状态
    for mask in range(1 << n):
        for last in range(n):
            # 如果当前状态没有访问到last基站,跳过
            if not (mask & (1 << last)):
                continue
            # 尝试扩展到下一个未访问的基站
            for next in range(n):
                # 如果已经访问过next基站,跳过
                if mask & (1 << next):
                    continue
                # 更新新的状态
                newMask = mask | (1 << next)
                dp[newMask][next] = min(dp[newMask][next], dp[mask][last] + s[last][next])
    
    # 最终结果,回到起点基站1
    res = float('inf')
    for last in range(n):
        if last == 0:
            continue  # 不考虑起点自身
        res = min(res, dp[FULL_MASK][last] + s[last][0])
    # 输出最短路径
    print(res)

if __name__ == "__main__":
    main()

七、JavaScript算法源码

const readline = require('readline');

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

let input = [];
rl.on('line', (line) => {
    input = input.concat(line.trim().split(/\s+/).map(Number));
}).on('close', () => {
    let index = 0;
    // 读取基站数量
    const n = input[index++];
    // 初始化距离矩阵
    const s = [];
    for(let i = 0; i < n; i++) {
        const row = [];
        for(let j = 0; j < n; j++) {
            row.push(input[index++]);
        }
        s.push(row);
    }
    
    // 全部基站的状态,使用位掩码表示
    const FULL_MASK = (1 << n) - 1;
    // 初始化动态规划数组,dp[mask][i] 表示访问过mask状态,最后访问的基站是i的最小距离
    const dp = Array.from({length: 1 << n}, () => Array(n).fill(Infinity));
    // 起点是基站1,对应索引0,访问了基站1的状态
    dp[1 << 0][0] = 0;
    
    // 遍历所有可能的状态
    for(let mask = 0; mask < (1 << n); mask++) {
        for(let last = 0; last < n; last++) {
            // 如果当前状态没有访问到last基站,跳过
            if( (mask & (1 << last)) === 0 ) continue;
            // 尝试扩展到下一个未访问的基站
            for(let next = 0; next < n; next++) {
                // 如果已经访问过next基站,跳过
                if(mask & (1 << next)) continue;
                // 更新新的状态
                const newMask = mask | (1 << next);
                dp[newMask][next] = Math.min(dp[newMask][next], dp[mask][last] + s[last][next]);
            }
        }
    }
    
    // 最终结果,回到起点基站1
    let res = Infinity;
    for(let last = 0; last < n; last++) {
        if(last === 0) continue; // 不考虑起点自身
        res = Math.min(res, dp[FULL_MASK][last] + s[last][0]);
    }
    // 输出最短路径
    console.log(res);
});

八、C算法源码

#include <stdio.h>
#include <limits.h>

int main(){
    int n;
    // 读取基站数量
    scanf("%d", &n);
    // 初始化距离矩阵
    int s[n][n];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            scanf("%d", &s[i][j]);
        }
    }
    
    // 全部基站的状态,使用位掩码表示
    int FULL_MASK = (1 << n) - 1;
    // 初始化动态规划数组,dp[mask][i] 表示访问过mask状态,最后访问的基站是i的最小距离
    long long dp[1<<n][n];
    for(int mask=0; mask<(1<<n); mask++){
        for(int i=0; i<n; i++){
            dp[mask][i] = LLONG_MAX / 2; // 避免溢出
        }
    }
    // 起点是基站1,对应索引0,访问了基站1的状态
    dp[1<<0][0] = 0;
    
    // 遍历所有可能的状态
    for(int mask=0; mask<(1<<n); mask++){
        for(int last=0; last<n; last++){
            // 如果当前状态没有访问到last基站,跳过
            if( (mask & (1<<last)) == 0 ) continue;
            // 尝试扩展到下一个未访问的基站
            for(int next=0; next<n; next++){
                // 如果已经访问过next基站,跳过
                if( mask & (1<<next) ) continue;
                // 更新新的状态
                int newMask = mask | (1<<next);
                if(dp[newMask][next] > dp[mask][last] + s[last][next]){
                    dp[newMask][next] = dp[mask][last] + s[last][next];
                }
            }
        }
    }
    
    // 最终结果,回到起点基站1
    long long res = LLONG_MAX;
    for(int last=0; last<n; last++){
        if(last == 0) continue; // 不考虑起点自身
        if(res > dp[FULL_MASK][last] + s[last][0]){
            res = dp[FULL_MASK][last] + s[last][0];
        }
    }
    // 输出最短路径
    printf("%lld\n", res);
    return 0;
}

九、C++算法源码

#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    // 读取基站数量
    cin >> n;
    // 初始化距离矩阵
    vector<vector<int>> s(n, vector<int>(n));
    for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) {
            cin >> s[i][j];
        }
    }
    
    // 全部基站的状态,使用位掩码表示
    int FULL_MASK = (1 << n) - 1;
    // 初始化动态规划数组,dp[mask][i] 表示访问过mask状态,最后访问的基站是i的最小距离
    vector<vector<long long>> dp(1<<n, vector<long long>(n, LLONG_MAX / 2));
    // 起点是基站1,对应索引0,访问了基站1的状态
    dp[1<<0][0] = 0;
    
    // 遍历所有可能的状态
    for(int mask=0; mask<(1<<n); mask++){
        for(int last=0; last<n; last++){
            // 如果当前状态没有访问到last基站,跳过
            if( (mask & (1<<last)) == 0 ) continue;
            // 尝试扩展到下一个未访问的基站
            for(int next=0; next<n; next++){
                // 如果已经访问过next基站,跳过
                if(mask & (1<<next)) continue;
                // 更新新的状态
                int newMask = mask | (1<<next);
                dp[newMask][next] = min(dp[newMask][next], dp[mask][last] + (long long)s[last][next]);
            }
        }
    }
    
    // 最终结果,回到起点基站1
    long long res = LLONG_MAX;
    for(int last=0; last<n; last++){
        if(last == 0) continue; // 不考虑起点自身
        res = min(res, dp[FULL_MASK][last] + (long long)s[last][0]);
    }
    // 输出最短路径
    cout << res;
    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GEE问题:筛选指定区域的Sentinel-1影像缺乏VH等波段

目录 问题简介 原始代码 原始代码 问题解析 修改后的代码 问题简介 亲爱的同事们&#xff0c;我正在尝试使用 SAR 图像 - Sentinel-1 来改进使用机器学习的地上生物量建模。我想处理 Sentinel 图像并将它们作为波段插入以增强模型。通过阅读文档&#xff0c;可用的极化&a…

前端编程艺术(3)---JavaScript

目录 1.JavaScript 1.输出 2.变量和数据类型 3.运算符 4.数组 5.函数 6.面向对象 7.ES6面向对象 2.BOM 1.document对象 3.DOM 4.JSON 1.JavaScript JavaScript是一种脚本编程语言&#xff0c;通常用于为网页增加交互性和动态效果。它是一种高级语言&#xff…

用js和css实现一行一行文字交替显示

用js和css实现&#xff0c;效果是&#xff1a;有多行文字&#xff0c;一行一行的交替显示&#xff0c;每隔几秒显示一行&#xff0c;循环显示。 代码如下&#xff0c;保存为html即可看到效果&#xff1a; <!DOCTYPE html> <html lang"en"> <hea…

心觉:梦想成真的三个核心步骤

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作190/1000天 梦想成真是每个人的愿望 但是希望你不要把“梦想成真”这四个字当成愿望或许愿&#xff0c;因为它实际上是一个成事的…

为什么芯片有多个不同的供电电压?

一、为什么芯片有多个不同的供电电压&#xff1f; 优化性能与功耗&#xff1a;芯片的核心部分&#xff08;Core&#xff09;和输入输出部分&#xff08;IO&#xff09;可能采用不同的电压。核心电压通常较低&#xff0c;以减少功耗和发热&#xff0c;提高能效&#xff1b;而IO电…

如何解决msvcp140.dll丢失,这6个方法可以解决msvcp140.dll丢失

在日常电脑使用中&#xff0c;可能会遇到一些常见问题&#xff0c;比如msvcp140.dll丢失或损坏。这个问题会导致程序无法正常运行&#xff0c;对我们的生活、工作造成困扰。本文将介绍6种解决msvcp140.dll丢失的方法&#xff0c;让大家能快速解决这个问题。 一&#xff0c;msvc…

25游卡(服务器)面试经验 游卡最常见面试问题总结

目录 【面试经历】 问题+详细答案 面试流程 面试攻略 【面试经历】 秋招目前面了十多家,第一家不开摄像头且表示麦不好要求找个耳机的。贴面经(纯八股) 1.HTTP与HTTPS 2.MTU如何设置,过大过小的后果 3.DNS过程 4.如何创建进程/线程,孤儿进程 5.java从文件到运行的过程…

大厂笔试现已经禁用本地IDE怎么看

如果我说本来面试做题这种事情就是反人类你相信吗&#xff1f; 这个罪恶的源头就是 Google&#xff0c;说是为了选择高素质的计算机编程水平的人才&#xff0c;然后把面试就变成了考试&#xff0c;最大的受益者当然是印度人了。 当把一个考察过程变成标准化的考试过程&#x…

每日一道算法题——二分查找

文章目录 开口闭口区分:1、问题2、示例3、解决方法&#xff08;1&#xff09;注意点&#xff08;2&#xff09;代码 开口闭口区分: 开口闭口区分: [1,2,3] 左闭右闭[1,2,3) 左闭右开(1,2,3] 左开右闭 开口如数组(1,2,3)不包含当前数据&#xff0c;也就是指只有2&#xff0c;闭口…

各省-科技创新、研发强度数据(2007-2022年)

研发强度通常指研究与试验发展&#xff08;R&D&#xff09;经费与国内生产总值&#xff08;GDP&#xff09;之比&#xff0c;是衡量一个国家或地区科技活动强度的重要指标。高研发强度往往意味着更强的科技创新能力和更快的技术进步速度。 从地区分布来看&#xff0c;研发…

什么是 HTTP 请求中的 preflight 类型请求

在浏览器的 HTTP 请求中&#xff0c;当我们使用 fetch API 或者 XMLHttpRequest 来进行跨域请求时&#xff0c;浏览器有时会发送一种称为 Preflight 的请求。这种请求是浏览器在实际发送跨域请求前&#xff0c;先与目标服务器进行的一次 “探测” 请求&#xff0c;以确认服务器…

java基础_异常总结详解

1 列举一些列举常见的运行时异常 运行时异常都是 RuntimeException 子类异常 NullPointerException - 空指针异常 ClassCastException - 类转换异常 IndexOutOfBoundsException - 下标越界异常 ArithmeticException - 计算异常 IllegalArgumentException - 非法参数异常 Numb…

C - Separated Lunch

题目链接: C - Separated Lunch (atcoder.jp) 题目描述: 大致意思是&#xff1a;有n个人&#xff0c;让你把他们分为两个组&#xff0c;然后分完后的这两个组的最大值最小为多少&#xff1f; 数据范围&#xff1a; 样例输入&#xff1a; 5 2 3 5 10 12 样例输出&#xff1a;…

二分查找算法——在排序数组中查找元素的第一个和最后一个位置

1.题目解析 题目来源&#xff1a;在排序数组中查找元素的第一个和最后一个位置——力扣 测试用例 2.算法原理 查找左端点 此时根据二段性&#xff0c;需要将数组分为大于target与小于target两部分&#xff0c;然后取出中点位置判断此时中点位置的值与target的大小关系&#xf…

SpringBoot校园资料分享平台:设计与实现

3系统分析 3.1可行性分析 通过对本校园资料分享平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本校园资料分享平台采用JAVA作为开发语言&#xff0c;Sprin…

基于Springboot+Vue的计算中心共享平台(含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统中…

vSAN02:容错、存储策略、文件服务、快照与备份、iSCSI

目录 vSAN容错条带化存储策略1. 创建新策略2. 应用存储策略 vSAN文件服务文件服务快照与备份 vSAN iSCSI目标服务 vSAN容错 FTT&#xff1a;Fault to Tolerance 允许故障数 故障域&#xff1a;每一台vSAN主机是一个故障域 - 假设3台超融合&#xff08;3计算1存储&#xff09;&…

2024年最新版本神马TV8.5影视APP源码 293TV影视点播系统源码搭建教程 神马TV8.2加强版反编译教程 保姆级小白可搭建 完整版本视频教程

2024年最新版的神马TV影视APP源码&#xff0c;版本号8.5&#xff0c;提供了前所未有的定制化选项和高级功能。用户可以轻松更换应用的包名和名称&#xff0c;确保品牌个性化。此外&#xff0c;该应用采用了动态域名加密技术&#xff0c;增强了数据传输的安全性。它支持自动切换…

【可视化大屏】将柱状图引入到html页面中

到这里还是用的死数据&#xff0c;先将柱状图引入html页面测试一下 根据上一步echarts的使用步骤&#xff0c;引入echarts.js后需要初始化一个实例对象&#xff0c;所以新建一个index.js文件来进行创建实例化对象和配置数据信息等。 //在index.html引入<script src"j…

Redis:zset类型

Redis&#xff1a;zset类型 zset命令ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZREVRANGEBYSCOREZPOPMAXBZPOPMAXZPOPMINBZPOPMINZRANKZREVRANKZSCOREZREMZREMRANGEBYRANKZREMRANGEBYSCOREZINCRBY 集合间操作ZINRERSTOREZUNIONSTORE 内部编码ziplistskiplist 在Redis中&…