当前位置: 首页 > news >正文

快递员的烦恼 - 华为OD统一考试

OD统一考试(C卷)

分值: 200分

题解: Java / Python / C++

alt

题目描述

快递公司每日早晨,给每位快递员推送需要淡到客户手中的快递以及路线信息,快递员自己又查找了一些客户与客户之间的路线距离信息,请你依据这些信息,给快递员设计一条最短路径,告诉他最短路径的距离。

  1. 不限制快递包裹送到客户手中的顺序,但必须保证都送到客户手中;

  2. 用例保证一定存在投递站到每位客户之间的路线,但不保证客户与客户之间有路线,客户位置及投递站均允许多次经过;

  3. 所有快递送完后,快递员需回到投递站;

输入描述

首行输入两个正整数n、m.

接下来n行,输入快递公司发布的客户快递信息,格式为:客户id 投递站到客户之间的距离distance

再接下来的m行,是快递员自行查找的客户与客户之间的距离信息,格式为:客户1id 客户2id distance

在每行数据中,数据与数据之间均以单个空格分割规格:

0 <=n <= 10
0 <= m <= 10
0 < 客户id <= 1000
0 < distance <= 10000

输出描述

最短路径距离,如无法找到,请输出-1

示例1

输入:
2 1
1 1000
2 1200
1 2 300输出:
2500说明:
快递员先把快递送到客户1手中,接下来直接走客户1到客户2之间的直通线路,最后走投递站和客户2之间的路,回到投递站,距离为1000+300+1200= 2500

示例2

输入:
5 1
5 1000
9 1200
17 300
132 700
500 2300
5 9 400输出:
9200

题解

这道题目属于图论中的最短路径问题。题目要求找到一条路径,使得快递员从投递站出发,依次经过所有客户,最后回到投递站,使得路径的总距离最短。

首先,我们需要构建一个图,图中的节点表示投递站和所有客户,边表示它们之间的距离。由于题目中给出了客户之间的距离信息,我们可以使用 Floyd 算法来计算任意两点之间的最短距离。

接下来,我们使用动态规划来求解最短路径。定义dp[state][last]表示当前情况下已经投递的客户集合为state,上一次投递的客户为last时,已经走过的最短距离。状态转移方程为:

dp[state | (1 << last)][last] = min(dp[state | (1 << last)][last], dp[state][i] + dist[i][last])

其中,state为二进制表示的已经投递的客户集合,state | (1 << last)表示将statelast位置设置为1,last 表示上一次投递的状态。dist[i][last]表示投递的客户的最短距离。

时间复杂度

Floyd-Warshall算法的时间复杂度为O(n3),动态规划的时间复杂度为O(2n * n2),总体时间复杂度为O(n3 + 2^n * n^2)。

空间复杂度

空间复杂度主要由存储距离矩阵和动态规划数组决定,为O(n^2 + 2^n * n)。

Java

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/*** @author code5bug*/
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt(), m = scanner.nextInt();int[][] dist = new int[n + 1][n + 1];for (int i = 0; i < dist.length; i++) Arrays.fill(dist[i], Integer.MAX_VALUE);// 客户id 和索引下标的对照表Map<Integer, Integer> idxMap = new HashMap<>();// 初始化客户id 到 投递站(0) 之间的距离for (int idx = 1; idx <= n; idx++) {int cid = scanner.nextInt();int distance = scanner.nextInt();dist[0][idx] = dist[idx][0] = distance;idxMap.put(cid, idx);}// 初始化客户与客户之间的距离for (int i = 0; i < m; i++) {int cid1 = scanner.nextInt(), cid2 = scanner.nextInt(), distance = scanner.nextInt();int idx1 = idxMap.get(cid1), idx2 = idxMap.get(cid2);dist[idx1][idx2] = dist[idx2][idx1] = distance;}// Floyd-Warshall算法 求出所有点之间的最短距离 时间复杂度为O(n^3)for (int k = 0; k <= n; k++) {dist[k][k] = 0;  // 自己到自己的距离为0for (int i = 0; i <= n; i++) {for (int j = 0; j <= n; j++) {dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);}}}// dp[state][last] 当前情况走过的最短距离// state 表示已经投递的客户 (指定二进制位为1表示已经投递),last表示上一次投递的客户int[][] dp = new int[1 << (n + 1)][n + 1];for (int i = 0; i < (1 << (n + 1)); i++) Arrays.fill(dp[i], Integer.MAX_VALUE);dp[1][0] = 0;  // 初始状态,在投递站for (int state = 0; state < (1 << (n + 1)); state++) {for (int i = 0; i <= n; i++) {if ((state >> i & 1) == 1 && dp[state][i] != Integer.MAX_VALUE) {    // 如果 i 已经投递 且 可达for (int last = 0; last <= n; last++) {dp[state | (1 << last)][last] = Math.min(dp[state | (1 << last)][last], dp[state][i] + dist[i][last]);}}}}System.out.println(dp[(1 << (n + 1)) - 1][0]);}
}

Python

from math import infn, m = map(int, input().split())
dist = [[inf] * (n + 1) for _ in range(n + 1)]# 客户id 和索引下标的对照表
idx_map = {}# 初始化客户id  到 投递站(0) 之间的距离
for idx in range(1, n + 1):cid, distance = map(int, input().split())dist[0][idx] = dist[idx][0] = distanceidx_map[cid] = idx# 初始化客户与客户之间的距离
for _ in range(m):cid1, cid2, distance = map(int, input().split())idx1, idx2 = idx_map[cid1], idx_map[cid2]dist[idx1][idx2] = dist[idx2][idx1] = distance# Floyd-Warshall算法 求出所有点之间的最短距离  时间复杂度为O(n^3)
for k in range(n + 1):dist[k][k] = 0  # 自己到自己的距离为0for i in range(n + 1):for j in range(n + 1):dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])f = [[inf] * (n + 1) for _ in range(1 << (n + 1))]
f[1][0] = 0# dp[state][last] 当前情况走过的最短距离
# state 表示已经投递的客户 (指定二进制位为1表示已范围),last表示上一次投递的客户
dp = [[inf] * (n + 1) for _ in range(1 << (n + 1))]
dp[1][0] = 0  # 初始状态,在投递站for state in range(1 << (n + 1)):for i in range(n + 1):if (state >> i) & 1 and dp[state][i] != inf:    # 如果 i 已经投递 且 可达for last in range(n + 1):dp[state | (1 << last)][last] = min(dp[state | (1 << last)][last], dp[state][i] + dist[i][last])print(dp[(1 << (n + 1)) - 1][0])

C++

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <climits>using namespace std;int main() {int n, m;cin >> n >> m;vector<vector<int>> dist(n + 1, vector<int>(n + 1, INT_MAX));// 客户id 和索引下标的对照表unordered_map<int, int> idxMap;// 初始化客户id 到 投递站(0) 之间的距离for (int idx = 1; idx <= n; idx++) {int cid, distance;cin >> cid >> distance;dist[0][idx] = dist[idx][0] = distance;idxMap[cid] = idx;}// 初始化客户与客户之间的距离for (int i = 0; i < m; i++) {int cid1, cid2, distance;cin >> cid1 >> cid2 >> distance;int idx1 = idxMap[cid1], idx2 = idxMap[cid2];dist[idx1][idx2] = dist[idx2][idx1] = distance;}// Floyd-Warshall算法 求出所有点之间的最短距离 时间复杂度为O(n^3)for (int k = 0; k <= n; k++) {dist[k][k] = 0;  // 自己到自己的距离为0for (int i = 0; i <= n; i++) {for (int j = 0; j <= n; j++) {dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);}}}// dp[state][last] 当前情况走过的最短距离// state 表示已经投递的客户 (指定二进制位为1表示已经投递),last表示上一次投递的客户vector<vector<int>> dp(1 << (n + 1), vector<int>(n + 1, INT_MAX));dp[1][0] = 0;  // 初始状态,在投递站for (int state = 0; state < (1 << (n + 1)); state++) {for (int i = 0; i <= n; i++) {if ((state >> i & 1) == 1 && dp[state][i] != INT_MAX) {    // 如果 i 已经投递 且 可达for (int last = 0; last <= n; last++) {dp[state | (1 << last)][last] = min(dp[state | (1 << last)][last], dp[state][i] + dist[i][last]);}}}}cout << dp[(1 << (n + 1)) - 1][0] << endl;return 0;
}

相关练习题

题号题目难易
LeetCode 29762976. 转换字符串的最小成本 I中等

‍❤️‍华为OD机试面试交流群每日真题分享): 加V时备注“华为od加群”

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

相关文章:

快递员的烦恼 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 快递公司每日早晨&#xff0c;给每位快递员推送需要淡到客户手中的快递以及路线信息&#xff0c;快递员自己又查找了一些客户与客户之间的路线距离信息&#xff0…...

css1基础选择器

大纲 一.标签选择器 比较简单&#xff0c;前面直接写目标标签 二.类选择器 应用 例子 三.多类名选择器&#xff08;调用时中间用空格隔开&#xff09; 四.id选择器 应用 五.通配符选择器 应用 六.总结...

【C语言】内联函数总结

内联函数定义 inline关键字是C99标准的型关键字&#xff0c;其作用是将函数展开&#xff0c;把函数的代码复制到每一个调用处。这样调用函数的过程就可以直接执行函数代码&#xff0c;而不发生跳转、压栈等一般性函数操作。可以节省时间&#xff0c;也会提高程序的执行速度。 …...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之MenuItemGroup组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之MenuItemGroup组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、MenuItemGroup组件 该组件用来展示菜单MenuItem的分组。 子组件 无 接…...

【Linux多线程编程】互斥锁及其使用

1、互斥锁 用于解决竞争问题的一种机制。 什么是竞争&#xff0c;竞争就是多个实体同时获取一个资源&#xff0c;例如多个线程写一个全局变量。 2、Linux如何使用互斥锁 以pthread为例&#xff0c;锁的创建和使用如下&#xff1a; /* 创建锁 */ pthread_mutex_t lock PTHR…...

RabbitMQ_00000

MQ的相关概念 RabbitMQ官网地址&#xff1a;https://www.rabbitmq.com RabbitMQ API地址&#xff1a;https://rabbitmq.github.io/rabbitmq-java-client/api/current/ 什么是MQ&#xff1f; MQ(message queue)本质是个队列&#xff0c;FIFO先入先出&#xff0c;只不过队列中…...

【linux】docker下homeassistant和nodered安装及配置

1、homeassistant安装 从 Docker Hub 上拉取 Home Assistant 的镜像文件 docker pull homeassistant/home-assistant 是运行 Home Assistant 容器 docker run -id --name"homeassistant" --privileged --restart always -p 8123:8123 -e TZAisa/Shanghai --nethost…...

Qt扩展-muParser数学公式解析

muParser数学公式解析 一、概述1. 针对速度进行了优化2. 支持的运算符3. 支持的函数4. 用户定义的常量5. 用户定义的变量6. 自定义值识别回调7. 其他功能 二、内置函数三、内置二元运算符四、三元运算符五、内置常量六、源码引入1. 源码文件2. 编译器开关1. MUP_BASETYPE2.MUP_…...

【Matplotlib】figure方法之图形的保存

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;matplotlib &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…...

数据库管理-第142期 DBA?DBA!(20240131)

数据库管理142期 2024-01-31 数据库管理-第142期 DBA&#xff1f;DBA&#xff01;&#xff08;20240131&#xff09;正文总结 数据库管理-第142期 DBA&#xff1f;DBA&#xff01;&#xff08;20240131&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09…...

react 之 zustand

zustand可以说是redux的平替 官网地址&#xff1a;https://zustand-demo.pmnd.rs/ 1.安装 npm i zustand2.基础使用 // zustand import { create } from zustand// 1. 创建store // 语法容易出错 // 1. 函数参数必须返回一个对象 对象内部编写状态数据和方法 // 2. set是用来…...

leetcode-回文链表

234. 回文链表 在此对比的值&#xff0c;不是节点 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def isPalindrome(self, head: Optional[ListNod…...

Pinia:一个Vue的状态管理库

Pinia的使用方法包括以下步骤&#xff1a; 安装Pinia&#xff1a;通过yarn或npm进行安装&#xff1a; yarn命令&#xff1a; yarn add pinianpm命令&#xff1a; npm install pinia创建根存储&#xff1a;在main.ts中引入Pinia插件&#xff0c;并创建一个根存储。这可以通过创建…...

2024 Flutter 重大更新,Dart 宏(Macros)编程开始支持,JSON 序列化有救

说起宏编程可能大家并不陌生&#xff0c;但是这对于 Flutter 和 Dart 开发者来说它一直是一个「遗憾」&#xff0c;这个「遗憾」体现在编辑过程的代码修改支持上&#xff0c;其中最典型的莫过于 Dart 的 JSON 序列化。 举个例子&#xff0c;目前 Dart 语言的 JSON 序列化高度依…...

云计算概述(云计算类型、技术驱动力、关键技术、特征、特点、通用点、架构层次)(二)

云计算概述&#xff08;二&#xff09; &#xff08;云计算类型、技术驱动力、关键技术、特征、特点、通用点、架构层次&#xff09; 目录 零、00时光宝盒 一、云计算类型&#xff08;以服务的内容或形态来分) 二、云计算的12种技术驱动力 三、云计算的关键技术 四、云计…...

物流平台架构设计与实践

随着电商行业的迅猛发展&#xff0c;物流行业也得到了极大的发展。从最初的传统物流到现在的智慧物流&#xff0c;物流技术和模式也在不断的更新与升级。物流平台作为连接电商和物流的重要媒介&#xff0c;其架构设计和实践显得尤为重要。 一、物流平台架构设计 1. 前端架构设…...

RedHat8.4安装邮件服务器

一、配置发件服务器 1.1 根据现场IP&#xff0c;配置主机名 vim /etc/hosts 192.168.8.120 mail.test.com 将主机名更改为邮件服务器域名mail.test.com 1.2 关闭防火墙&#xff0c;禁止开机启动 systemctl stop firewalld systemctl disable firewalld 1.3 关闭selinux v…...

Linux Shell系列--dirname 去除基本文件名

一、目的 上一篇中我们介绍了basename命令的使用&#xff0c;本篇我们介绍dirname命令&#xff0c;dirname 命令与 basename 互补&#xff0c;它负责删除路径中的基本文件名部分&#xff08;包括扩展名&#xff09;&#xff0c;只保留目录部分。 二、介绍 dirname首先去除字符…...

池化技术的总结

文章目录 1.什么是池化技术2.池化技术的应用一、连接池二、线程池三、内存池 3.池化技术的总结 1.什么是池化技术 池化技术指的是提前准备一些资源&#xff0c;在需要时可以重复使用这些预先准备的资源。 在系统开发过程中&#xff0c;我们经常会用到池化技术。通俗的讲&am…...

H5简约星空旋转引导页源码

H5简约星空旋转引导页源码 源码介绍&#xff1a;一款带有星空旋转背景特效的源码&#xff0c;带有四个按钮 下载地址&#xff1a; https://www.changyouzuhao.cn/11655.html...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...