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

【双机位A卷】华为OD笔试之【哈希表】双机位A-采购订单【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解

可上 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳 od1441了解算法冲刺训练(备注【CSDN】否则不通过)

文章目录

  • 相关推荐阅读
  • 题目描述与示例
    • 题目描述
    • 输入描述
    • 输出描述
    • 补充说明
    • 示例一
      • 输入
      • 输出
      • 说明
    • 示例二
      • 输入
      • 输出
      • 说明
    • 示例三
      • 输入
      • 输出
      • 说明
  • 解题思路
  • 代码
    • Python
    • Java
    • C++
    • C
    • Node JavaScript
    • Go
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

相关推荐阅读

  • 【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
  • 【华为OD机考】2025C+2025B+2024E+D卷真题【完全原创题解 | 详细考点分类 | 不断更新题目】
  • 【华为OD笔试】双机位A+2025C+2025B+2024E+D卷真题机考套题汇总【真实反馈,不断更新,限时免费】
  • 【华为OD笔试】2024E+D卷命题规律解读【分析500+场OD笔试考点总结】
  • 【华为OD流程】性格测试选项+注意事项】

题目练习网址:【哈希表】双机位A-采购订单

题目描述与示例

题目描述

在一个采购系统中,采购申请(PR)需要经过审批后才能生成采购订单(PO)。每个PR包含商品的单价(假设相同商品的单价一定是一样的)及数量信息。

系统要求对商品进行分类处理:单价高于100元的商品需要单独处理,单价低于或等于100元的相同商品可以合并到同一采购订单PO中。针对单价低于100的小额订单,如果量大可以打折购买。

具体规则如下:

如果PR状态为"审批通过",则将其商品加入到PO中。如果PR的状态为"审批拒绝"或"待审批",则忽略该PR。

对于单价高于100元的商品,每个商品单独生成一条PO记录。对于单价低于或等于100元的商品,将相同商品的数量合并到一条PO记录中。

如果商品单价<100且商品数量>=100,则单价打9折。

输入描述

第一行包含整数N,表示PR的数量。

接下来N行,每行包含四个用空格分割的整数,按顺序表示:商品ID,数量,单价,PR状态 (0表示审批通过,1表示审批拒绝,2表示待审批)

输出描述

输出若干行,每行表示一条PO记录,按以下格式输出:

对于单价高于100元的商品:商品ID 数量 单价

对于单价低于或等于100元的商品: 商品ID 总数量 打折后的单价(向上取整)

输出的PO记录按商品ID升序升序排列,相同商品按照数量降序排列

补充说明

  • 2 <= n <= 1000
  • 1 <= 商品价格 <= 200
  • 1 <= 商品数量 <= 1000
  • 1 <= 商品编号 <= 1000

示例一

输入

2
1 200 90 0
2 30 101 0

输出

1 200 81
2 30 101

说明

商品1的原始单价为90,审批通过,生成一条PO,满足打折条件,打折后单价为81。

商品2的单价为101,审批通过,生成一条PO

示例二

输入

3
1 10 90 0
1 5 90 0
2 8 120 0

输出

1 15 90
2 8 120

说明

PR1和PR2均为商品1,单价90,审批通过,单价低于100元,合并数量为15

PR3为商品2,单价120元,审批通过,单价高于100元,单独生成一条PO记录。

示例三

输入

4
1 5 80 0
2 3 120 0
3 2 90 1
4 10 150 2

输出

1 5 80
2 3 120

说明

PR1:商品1,单价80元,审批通过,单价低于100元,合并到PO中。

PR2:商品2,单价120元,审批通过,单价高于100元,单独生成一条PO记录。

PR3:审批拒绝, 忽略。

PR4:待审批,忽略。

解题思路

题目的细节较多,需要仔细读题。注意以下几个点

  • 审批状态必须为0,如果审批状态为12,则直接忽略该条订单
  • 单价 > 100,不合并订单,不打折
  • 单价 = 100,合并订单,不打折
  • 单价 < 100,合并订单,打折

单价 = 100的情况,属于特殊的边界情况,在题目中需要仔细读题才能判断出来。

当单价 ≤ 100时,本题涉及到多个同类型商品订单的合并过程

容易想到用哈希表来维护这个过程。

我们可以设计一个哈希表dic,其中key为商品编号,由于需要同时储存商品单价和商品数量,value可以设计为一个长度为2的数组来储存上述信息。

而不需要合并的订单,我们可以直接用另一个列表lst来储存,同时储存编号,单价,数量

故可用如下代码来完成数组的更新和哈希表的构建

# 储存有效订单的列表
lst = list()
# 储存单价小于等于100的商品信息的哈希表
dic = dict()# 循环n次
for _ in range(n):# 输入订单信息,包含编号、数量、单价、状态idx, num, price, state = map(int, input().split())# 如果状态为1或2,则属于无效订单,直接跳过if state != 0:continue# 如果单价大于100,则需要单独储存# 将其编号、数量、单价作为一个三元组存入lst中# 储存后跳过后续判断if price > 100:lst.append([idx, num, price])continue# 如果单价小于等于100# 判断其是否位于哈希表中# 如果是首次出现,则以编号为key# 数量和单价构成的二元组作为value# 构建键值对if idx not in dic:dic[idx] = [num, price]# 如果当前商品已经存在于哈希表中# 则将数量累加到哈希表中else:dic[idx][0] += num

哈希表构建完毕之后,我们需要再次遍历整个哈希表,将其中可以打折的商品进行单价的修改。

# 再次遍历哈希表中的所有键值对
for idx in dic:num, price = dic[idx]# 如果数量大于等于100且单价小于100# 则单价打9折,向上取整if num >= 100 and price < 100:dic[idx][1] = ceil(price * 0.9)

接下来我们需要将哈希表dic中的键值对,同样根据编号,数量,单价的格式合并到lst中。

# 再次遍历哈希表中的所有键值对
# 将更新后的商品信息,按照编号、数量、单价的三元组格式
# 存入lst中
for idx in dic:num, price = dic[idx]lst.append([idx, num, price])

最后将lst中的元素进行排序,按照先编号升序排序,后根据数量降序排序的规则进行排序。即

# 对lst中的元素进行排序
# 先按照编号升序排序,在按照数量降序排序
lst.sort(key = lambda x: (x[0], -x[1]))

代码

Python

# 欢迎来到「欧弟算法 - 华为OD全攻略」,收录华为OD题库、面试指南、八股文与学员案例!
# 地址:https://www.odalgo.com
# 华为OD机试刷题网站:https://www.algomooc.com
# 添加微信 278166530 获取华为 OD 笔试真题题库和视频# 题目:【哈希表】双机位A-采购订单
# 分值:100
# 作者:许老师-闭着眼睛学数理化
# 算法:哈希表/排序
# 代码看不懂的地方,请直接在群上提问from math import ceil# 输入订单条数
n = int(input())# 储存有效订单的列表
lst = list()
# 储存单价小于等于100的商品信息的哈希表
dic = dict()# 循环n次
for _ in range(n):# 输入订单信息,包含编号、数量、单价、状态idx, num, price, state = map(int, input().split())# 如果状态为1或2,则属于无效订单,直接跳过if state != 0:continue# 如果单价大于100,则需要单独储存# 将其编号、数量、单价作为一个三元组存入lst中# 储存后跳过后续判断if price > 100:lst.append([idx, num, price])continue# 如果单价小于等于100# 判断其是否位于哈希表中# 如果是首次出现,则以编号为key# 数量和单价构成的二元组作为value# 构建键值对if idx not in dic:dic[idx] = [num, price]# 如果当前商品已经存在于哈希表中# 则将数量累加到哈希表中else:dic[idx][0] += num# 再次遍历哈希表中的所有键值对
for idx in dic:num, price = dic[idx]# 如果数量大于等于100且单价小于100# 则单价打9折,向上取整if num >= 100 and price < 100:dic[idx][1] = ceil(price * 0.9)# 再次遍历哈希表中的所有键值对
# 将更新后的商品信息,按照编号、数量、单价的三元组格式
# 存入lst中
for idx in dic:num, price = dic[idx]lst.append([idx, num, price])# 对lst中的元素进行排序
# 先按照编号升序排序,在按照数量降序排序
lst.sort(key = lambda x: (x[0], -x[1]))# 输出答案
for idx, num, price in lst:print(idx, num, price)

Java

// 欢迎来到「欧弟算法 - 华为OD全攻略」,收录华为OD题库、面试指南、八股文与学员案例!
// 地址:https://www.odalgo.com
// 华为OD机试刷题网站:https://www.algomooc.com
// 添加微信 278166530 获取华为 OD 笔试真题题库和视频// 题目:【哈希表】双机位A-采购订单
// 分值:100
// 作者:许老师-闭着眼睛学数理化
// 算法:哈希表/排序
// 代码看不懂的地方,请直接在群上提问import java.util.*;
import java.io.*;public class Main {public static void main(String[] args) throws IOException {Scanner sc = new Scanner(System.in);// 输入订单条数int n = sc.nextInt();// 储存有效订单的列表List<int[]> lst = new ArrayList<>();// 储存单价小于等于100的商品信息的哈希表Map<Integer, int[]> dic = new HashMap<>();// 循环n次for (int i = 0; i < n; i++) {// 输入订单信息,包含编号、数量、单价、状态int idx = sc.nextInt();int num = sc.nextInt();int price = sc.nextInt();int state = sc.nextInt();// 如果状态为1或2,则属于无效订单,直接跳过if (state != 0) {continue;}// 如果单价大于100,则需要单独储存// 将其编号、数量、单价作为一个三元组存入lst中if (price > 100) {lst.add(new int[] {idx, num, price});continue;}// 如果单价小于等于100// 判断其是否位于哈希表中if (!dic.containsKey(idx)) {dic.put(idx, new int[] {num, price});} else {// 如果已存在,则数量累加dic.get(idx)[0] += num;}}// 遍历哈希表中的所有键值对for (Map.Entry<Integer, int[]> entry : dic.entrySet()) {int idx = entry.getKey();int num = entry.getValue()[0];int price = entry.getValue()[1];// 如果数量大于等于100且单价小于100,则单价打9折,向上取整if (num >= 100 && price < 100) {entry.getValue()[1] = (int) Math.ceil(price * 0.9);}}// 将更新后的哈希表内容转为三元组形式加入lst中for (Map.Entry<Integer, int[]> entry : dic.entrySet()) {int idx = entry.getKey();int num = entry.getValue()[0];int price = entry.getValue()[1];lst.add(new int[] {idx, num, price});}// 对lst进行排序,先按照编号升序,再按照数量降序lst.sort((a, b) -> {if (a[0] != b[0]) {return a[0] - b[0];}return b[1] - a[1]; // 数量降序});// 输出答案for (int[] item : lst) {System.out.println(item[0] + " " + item[1] + " " + item[2]);}}
}

C++

// 欢迎来到「欧弟算法 - 华为OD全攻略」,收录华为OD题库、面试指南、八股文与学员案例!
// 地址:https://www.odalgo.com
// 华为OD机试刷题网站:https://www.algomooc.com
// 添加微信 278166530 获取华为 OD 笔试真题题库和视频// 题目:【哈希表】双机位A-采购订单
// 分值:100
// 作者:许老师-闭着眼睛学数理化
// 算法:哈希表/排序
// 代码看不懂的地方,请直接在群上提问#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <cmath>
using namespace std;int main() {int n;// 输入订单条数cin >> n;// 储存有效订单的列表(三元组:idx, num, price)vector<vector<int>> lst;// 储存单价 <= 100 的商品信息的哈希表unordered_map<int, pair<int, int>> dic;// 循环n次for (int i = 0; i < n; i++) {int idx, num, price, state;cin >> idx >> num >> price >> state;// 如果状态为1或2,则属于无效订单,直接跳过if (state != 0) continue;// 如果单价 > 100,直接入列表,不合并if (price > 100) {lst.push_back({idx, num, price});continue;}// 如果单价 <= 100,合并相同编号订单(只累加数量,保留首次价格)if (dic.find(idx) == dic.end()) {dic[idx] = {num, price};} else {dic[idx].first += num;  // 数量累加}}// 遍历哈希表,处理折扣for (auto &p : dic) {int &num = p.second.first;int &price = p.second.second;// 数量>=100 且 单价<100,打9折,向上取整if (num >= 100 && price < 100) {price = ceil(price * 0.9);}}// 将dic内容写回lstfor (auto &p : dic) {int idx = p.first;int num = p.second.first;int price = p.second.second;lst.push_back({idx, num, price});}// 排序:编号升序,数量降序sort(lst.begin(), lst.end(), [](const vector<int> &a, const vector<int> &b) {if (a[0] != b[0]) return a[0] < b[0];return a[1] > b[1];});// 输出答案for (auto &item : lst) {cout << item[0] << " " << item[1] << " " << item[2] << endl;}return 0;
}

C

// 欢迎来到「欧弟算法 - 华为OD全攻略」,收录华为OD题库、面试指南、八股文与学员案例!
// 地址:https://www.odalgo.com
// 华为OD机试刷题网站:https://www.algomooc.com
// 添加微信 278166530 获取华为 OD 笔试真题题库和视频// 题目:【哈希表】双机位A-采购订单
// 分值:100
// 作者:许老师-闭着眼睛学数理化
// 算法:哈希表/排序
// 代码看不懂的地方,请直接在群上提问#include <stdio.h>
#include <stdlib.h>
#include <math.h>#define MAX_ORDERS 10000   // 最大订单数// 定义结构体用于存储订单信息(编号,数量,单价)
typedef struct {int idx;int num;int price;
} Order;// 定义哈希表节点
typedef struct HashNode {int idx;int num;int price;struct HashNode *next;
} HashNode;#define HASH_SIZE 20011  // 哈希表大小(素数)// 哈希函数(取模)
int hash(int key) {return key % HASH_SIZE;
}// 在哈希表中查找订单编号对应节点
HashNode* find(HashNode* table[], int idx) {int h = hash(idx);HashNode *cur = table[h];while (cur) {if (cur->idx == idx) return cur;cur = cur->next;}return NULL;
}// 插入或更新哈希表节点
void insert_or_update(HashNode* table[], int idx, int num, int price) {int h = hash(idx);HashNode *node = find(table, idx);if (node) {node->num += num;  // 如果存在,则数量累加} else {// 否则新建节点插入链表头node = (HashNode*)malloc(sizeof(HashNode));node->idx = idx;node->num = num;node->price = price;node->next = table[h];table[h] = node;}
}int compare(const void *a, const void *b) {Order *x = (Order*)a;Order *y = (Order*)b;if (x->idx != y->idx) return x->idx - y->idx;     // 按编号升序return y->num - x->num;                            // 数量降序
}int main() {int n;// 输入订单条数scanf("%d", &n);Order lst[MAX_ORDERS];  // 存储有效订单(三元组)int lst_size = 0;// 初始化哈希表HashNode* dic[HASH_SIZE] = {0};// 循环n次读取订单for (int i = 0; i < n; i++) {int idx, num, price, state;scanf("%d %d %d %d", &idx, &num, &price, &state);// 如果状态为1或2,则属于无效订单,直接跳过if (state != 0) continue;// 如果单价 > 100 直接入数组,不合并if (price > 100) {lst[lst_size++] = (Order){idx, num, price};continue;}// 否则加入哈希表中累加数量insert_or_update(dic, idx, num, price);}// 遍历哈希表,处理折扣for (int i = 0; i < HASH_SIZE; i++) {HashNode *cur = dic[i];while (cur) {if (cur->num >= 100 && cur->price < 100) {cur->price = (int)ceil(cur->price * 0.9);  // 单价打9折,向上取整}cur = cur->next;}}// 将哈希表内容写回数组for (int i = 0; i < HASH_SIZE; i++) {HashNode *cur = dic[i];while (cur) {lst[lst_size++] = (Order){cur->idx, cur->num, cur->price};cur = cur->next;}}// 排序:编号升序,数量降序qsort(lst, lst_size, sizeof(Order), compare);// 输出结果for (int i = 0; i < lst_size; i++) {printf("%d %d %d\n", lst[i].idx, lst[i].num, lst[i].price);}return 0;
}

Node JavaScript

// 欢迎来到「欧弟算法 - 华为OD全攻略」,收录华为OD题库、面试指南、八股文与学员案例!
// 地址:https://www.odalgo.com
// 华为OD机试刷题网站:https://www.algomooc.com
// 添加微信 278166530 获取华为 OD 笔试真题题库和视频// 题目:【哈希表】双机位A-采购订单
// 分值:100
// 作者:许老师-闭着眼睛学数理化
// 算法:哈希表/排序
// 代码看不懂的地方,请直接在群上提问const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout
});let input = [];
rl.on('line', (line) => {input.push(line.trim());
});rl.on('close', () => {let index = 0;// 输入订单条数const n = parseInt(input[index++]);// 储存有效订单的列表const lst = [];// 储存单价小于等于100的商品信息的哈希表const dic = new Map();// 循环n次读取订单信息for (let i = 0; i < n; i++) {const [idx, num, price, state] = input[index++].split(' ').map(Number);// 如果状态为1或2,则属于无效订单,直接跳过if (state !== 0) {continue;}// 如果单价大于100,单独存入lstif (price > 100) {lst.push([idx, num, price]);continue;}// 单价小于等于100的商品处理逻辑if (!dic.has(idx)) {dic.set(idx, [num, price]);} else {dic.get(idx)[0] += num; // 累加数量}}// 遍历哈希表,处理满足折扣条件的商品dic.forEach((value, idx) => {const [num, price] = value;if (num >= 100 && price < 100) {dic.set(idx, [num, Math.ceil(price * 0.9)]);}});// 将哈希表中的订单加入lst列表dic.forEach((value, idx) => {const [num, price] = value;lst.push([idx, num, price]);});// 对lst进行排序:先编号升序,再数量降序lst.sort((a, b) => a[0] !== b[0] ? a[0] - b[0] : b[1] - a[1]);// 输出答案lst.forEach(item => {console.log(item.join(' '));});
});

Go

// 欢迎来到「欧弟算法 - 华为OD全攻略」,收录华为OD题库、面试指南、八股文与学员案例!
// 地址:https://www.odalgo.com
// 华为OD机试刷题网站:https://www.algomooc.com
// 添加微信 278166530 获取华为 OD 笔试真题题库和视频// 题目:【哈希表】双机位A-采购订单
// 分值:100
// 作者:许老师-闭着眼睛学数理化
// 算法:哈希表/排序
// 代码看不懂的地方,请直接在群上提问package mainimport ("bufio""fmt""math""os""sort"
)func main() {reader := bufio.NewReader(os.Stdin)var n int// 输入订单条数fmt.Fscan(reader, &n)// 储存有效订单的列表lst := make([][]int, 0)// 储存单价小于等于100的商品信息的哈希表(key=编号, value=[数量, 单价])dic := make(map[int][]int)// 循环读取订单for i := 0; i < n; i++ {var idx, num, price, state intfmt.Fscan(reader, &idx, &num, &price, &state)// 如果状态为1或2,则属于无效订单if state != 0 {continue}// 单价大于100,则加入lstif price > 100 {lst = append(lst, []int{idx, num, price})continue}// 单价小于等于100:处理哈希表if _, exists := dic[idx]; !exists {dic[idx] = []int{num, price}} else {dic[idx][0] += num // 累加数量}}// 遍历哈希表中的订单,处理折扣for idx, data := range dic {num, price := data[0], data[1]// 数量大于等于100 且 单价小于100 的订单,单价打9折(向上取整)if num >= 100 && price < 100 {dic[idx][1] = int(math.Ceil(float64(price) * 0.9))}}// 将最终哈希表数据加入lstfor idx, data := range dic {lst = append(lst, []int{idx, data[0], data[1]})}// 对lst排序:先编号升序,再数量降序sort.Slice(lst, func(i, j int) bool {if lst[i][0] != lst[j][0] {return lst[i][0] < lst[j][0]}return lst[i][1] > lst[j][1]})// 输出结果for _, item := range lst {fmt.Printf("%d %d %d\n", item[0], item[1], item[2])}
}

时空复杂度

时间复杂度:O(n)。所有操作都仅需遍历一次数组或者哈希表。

空间复杂度:O(n)。哈希表和列表所占空间。


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华子OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务1000+同学成功上岸!

  • 课程讲师为全网200w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 90+天陪伴式学习,100+直播课时,300+动画图解视频,500+LeetCode经典题,500+华为OD真题/大厂真题,还有简历修改、模拟面试、陪伴小群、资深HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1441或了解更多

http://www.dtcms.com/a/582041.html

相关文章:

  • 第十章、GPT1:Improving Language Understanding by Generative Pre-Training(代码部分)
  • 2025全球生成式人工智能AIGC产业全景与行业应用研究报告|附900+份报告PDF、数据、可视化模板汇总下载
  • 网站广告销售怎们做网站开发确认书
  • 常见的模型性能评估图表案例解读
  • 网站推广服务网站连锁金融网站怎么做
  • 从协议中成长
  • ⚡️2025-11-07GitHub日榜Top5|AI舆情分析系统
  • 云建站淘宝客网页设计教程 表单
  • 石河子农八师建设兵团社保网站餐饮营销方案
  • P1012 [NOIP 1998 提高组] 拼数
  • 第四阶段C#通讯开发-9:网络协议Modbus下的TCP与UDP
  • 《计算机操作系统》_并发 bug 和应对 (死锁/数据竞争/原子性违反;防御性编程和动态分析)20251106
  • 【算法】递归的艺术:从本质思想到递归树,深入剖析算法的性能权衡
  • 网上怎么做网站赚钱seo初级入门教程
  • MySQL GROUP BY 和 GROUP_CONCAT 使用方法总结,group by后将其他的字段整合到一个字段中 并通过逗号链接或指定其他链接符号
  • 数字人|数字人企业技术派选择
  • 简单实现文字两端对齐
  • Flink Rebalance触发乱序的问题
  • 联合建设官方网站公司邮箱怎么在手机上登录
  • 代理龙华网站建设深圳英迈思做网站好么
  • UE网络复制中的可靠函数是什么意思 什么时候要勾选什么时候不勾?
  • 沈阳做网站建设微信公众号小程序开发教程
  • slice在Python和Go中的异同
  • 科技公司网站设计公司天津定制开发网站
  • 3 个近期 yyds 的 AI 开源项目, 有点绝。
  • 智启未来 共筑开放新生态——2025进博会人工智能亮点纷呈
  • python函数及面向过程高级特性
  • python+django/flask的莱元元电商数据分析系统_电商销量预测
  • Git分支创建与推送全攻略
  • python+django/flask基于Echarts+Python的图书零售监测系统设计与实现(带大屏)