华为OD机试 - 小朋友分组最少调整次数 - 贪心算法(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
n (3 ≤ n ≤ 90000 且可以整除 3) 个学生排成一排,学生编号分别是 1 到 n,n 为 3 的整数倍数,老师随机抽签决定将所有学生分成 m 个 3 人的小组(n = 3 * m)。
为了便于同组学生交流,老师决定将小组成员安排到一起,也就是同组成员彼此相连,同组任意两个成员之间无其它组的成员。
因此老师决定调整队伍,老师每次可以调整任意一名学生到队伍的任意位置,计为调整了一次,请计算最少调整多少次可以达到目标。
注意:对于小组之间没有顺序要求,同组学生之间没有顺序要求。
二、输入描述
第一行输入初始排列顺序序列
第二行输入分组排列顺序序列
三、输出描述
输出一个整数k,表示至少调整k次。
四、测试用例
测试用例1:
1、输入
4 2 8 5 3 6 1 9 7
6 3 1 2 4 8 7 9 5
2、输出
1
3、说明
只有一个组(例如 [4, 2, 8] 对应的组号)需要调整位置,使其成员在最终排列中相邻。这意味着只需要一次调整就能实现目标排列。因此,输出结果为 1,表示至少需要一次调整。
测试用例2:
1、输入
8 9 7 5 6 3 2 1 4
7 8 9 4 2 1 3 5 6
2、输出
0
3、说明
每组3个学生的编号在初始排列和目标排列中的组号顺序已经是对应的,并且组内成员在初始排列中已经彼此相邻。
通过检查可以发现,每个组的成员在初始排列中已经满足相邻的条件,因此不需要进行任何调整。
五、解题思路
这道题的目的是通过最少的调整次数,将一组学生按照指定的目标顺序排列,使得同组的学生在最终排列中彼此相连。题目的核心在于寻找一种策略,能够有效地将学生移动到合适的位置,同时最小化移动次数。
在计算调整次数时,采用了一种贪心的策略,优先处理需要最少调整的情况(如两两交换),从而减少整体调整次数。
(1)将学生编号映射为组号:
我们的目标是将学生编号转化为组号。因为每个组有3个学生,我们可以通过将目标排列中的每个学生编号映射到其组号(即编号除以3)来得到初始序列中每个学生的目标组号。
(2)记录组号的位置:
我们需要记录每个组号在初始排列中的位置。为此,我们创建一个数组列表,每个列表存储对应组号在初始排列中出现的位置。
(3)计算最少调整次数:
我们通过遍历每个组的位置列表来计算是否需要调整。如果一个组的所有成员在初始序列中已经连续排列,那么不需要调整;否则,需要进行一次调整。
如果一个组只有一个成员,则需要两次调整,因为要将其与另两个成员排在一起。如果有两个成员且它们间隔较大,也需要一次调整。
(4)计算组间交错:
为了避免多余的调整,计算组间的交错情况。如果一个组的成员之间有其他组的成员插入,这表明需要额外的调整。通过遍历整个组号序列,记录每个组号的出现次数,我们可以发现是否存在组间交错,并调整次数。
(5)输出最小调整次数:
最后,我们取前述计算出的两种调整方法的最小值作为最终的最小调整次数。
六、Python算法源码
# 导入必要的模块
import sysdef main():# 读取输入的初始排列顺序initial_order = list(map(int, sys.stdin.readline().strip().split()))# 读取输入的目标排列顺序target_order = list(map(int, sys.stdin.readline().strip().split()))student_count = len(initial_order)group_count = student_count // 3# 创建一个映射数组,将学生编号映射到目标序列中的组号group_mapping = [0] * (student_count + 1)for i in range(student_count):group_mapping[target_order[i]] = i // 3# 将初始顺序转换为组号数组group_order = [group_mapping[student] for student in initial_order]# 创建一个列表数组,用于存储每个组号在初始序列中出现的位置group_positions = [[] for _ in range(group_count)]for i, group in enumerate(group_order):group_positions[group].append(i)minimum_moves = 0# 遍历每个组的位置列表,计算需要的最少移动次数for positions in group_positions:if len(positions) == 3:# 如果一个组有3个成员,检查他们是否连续if positions[1] - positions[0] > 1 or positions[2] - positions[1] > 1:minimum_moves += 1elif len(positions) == 2:# 如果一个组有2个成员,检查他们是否间隔过大if positions[1] - positions[0] > 2:minimum_moves += 1elif len(positions) == 1:# 如果一个组只有1个成员,最坏情况需要两次调整minimum_moves += 2# 通过计算组间的交错情况,可能减少调整次数encountered_groups = set()overlap_adjustments = 0for group in group_order:if group not in encountered_groups:encountered_groups.add(group)else:overlap_adjustments += 1# 取两种调整方法的最小值minimum_moves = min(minimum_moves, overlap_adjustments)# 输出最小调整次数print(minimum_moves)# 调用主函数
if __name__ == "__main__":main()
七、JavaScript算法源码
// 使用Node.js的readline模块读取输入
const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout
});let inputLines = [];rl.on('line', (line) => {inputLines.push(line.trim());if (inputLines.length === 2) {rl.close();}
});rl.on('close', () => {// 读取初始排列顺序const initialOrder = inputLines[0].split(' ').map(Number);// 读取目标排列顺序const targetOrder = inputLines[1].split(' ').map(Number);const studentCount = initialOrder.length;const groupCount = studentCount / 3;// 创建一个映射数组,将学生编号映射到目标序列中的组号const groupMapping = new Array(studentCount + 1).fill(0);for (let i = 0; i < studentCount; i++) {groupMapping[targetOrder[i]] = Math.floor(i / 3);}// 将初始顺序转换为组号数组const groupOrder = initialOrder.map(student => groupMapping[student]);// 创建一个数组列表的数组,用于存储每个组号在初始序列中出现的位置const groupPositions = Array.from({length: groupCount}, () => []);for (let i = 0; i < groupOrder.length; i++) {groupPositions[groupOrder[i]].push(i);}let minimumMoves = 0;// 遍历每个组的位置列表,计算需要的最少移动次数for (const positions of groupPositions) {if (positions.length === 3) {// 如果一个组有3个成员,检查他们是否连续if (positions[1] - positions[0] > 1 || positions[2] - positions[1] > 1) {minimumMoves++;}} else if (positions.length === 2) {// 如果一个组有2个成员,检查他们是否间隔过大if (positions[1] - positions[0] > 2) {minimumMoves++;}} else if (positions.length === 1) {// 如果一个组只有1个成员,最坏情况需要两次调整minimumMoves += 2;}}// 通过计算组间的交错情况,可能减少调整次数const encounteredGroups = new Set();let overlapAdjustments = 0;for (const group of groupOrder) {if (!encounteredGroups.has(group)) {encounteredGroups.add(group);} else {overlapAdjustments++;}}// 取两种调整方法的最小值minimumMoves = Math.min(minimumMoves, overlapAdjustments);// 输出最小调整次数console.log(minimumMoves);
});
八、C算法源码
#include <stdio.h>
#include <stdlib.h>// 主函数
int main() {// 定义变量int n = 0;int initialOrder[90000];int targetOrder[90000];// 读取初始排列顺序while (scanf("%d", &initialOrder[n]) != EOF && getchar() != '\n') {n++;}// 读取目标排列顺序int m = 0;while (scanf("%d", &targetOrder[m]) != EOF && getchar() != '\n') {m++;}// 计算组数int groupCount = n / 3;// 创建组映射数组,将学生编号映射到组号int *groupMapping = (int *)malloc((n + 1) * sizeof(int));for (int i = 0; i < m; i++) {groupMapping[targetOrder[i]] = i / 3;}// 将初始顺序转换为组号数组int groupOrder[90000];for (int i = 0; i < n; i++) {groupOrder[i] = groupMapping[initialOrder[i]];}// 创建组位置数组int **groupPositions = (int **)malloc(groupCount * sizeof(int *));int *counts = (int *)calloc(groupCount, sizeof(int));for (int i = 0; i < groupCount; i++) {groupPositions[i] = (int *)malloc(3 * sizeof(int));}// 记录每个组的位置for (int i = 0; i < n; i++) {int group = groupOrder[i];groupPositions[group][counts[group]++] = i;}int minimumMoves = 0;// 遍历每个组,计算调整次数for (int i = 0; i < groupCount; i++) {if (counts[i] == 3) {if (groupPositions[i][1] - groupPositions[i][0] > 1 || groupPositions[i][2] - groupPositions[i][1] > 1) {minimumMoves++;}} else if (counts[i] == 2) {if (groupPositions[i][1] - groupPositions[i][0] > 2) {minimumMoves++;}} else if (counts[i] == 1) {minimumMoves += 2;}}// 计算组间的交错情况int *encounteredGroups = (int *)calloc(groupCount, sizeof(int));int overlapAdjustments = 0;for (int i = 0; i < n; i++) {int group = groupOrder[i];if (!encounteredGroups[group]) {encounteredGroups[group] = 1;} else {overlapAdjustments++;}}// 取最小调整次数if (overlapAdjustments < minimumMoves) {minimumMoves = overlapAdjustments;}// 输出结果printf("%d\n", minimumMoves);// 释放内存free(groupMapping);for (int i = 0; i < groupCount; i++) {free(groupPositions[i]);}free(groupPositions);free(counts);free(encounteredGroups);return 0;
}
九、C++算法源码
#include <bits/stdc++.h>
using namespace std;int main(){ios::sync_with_stdio(false);cin.tie(0);// 读取初始排列顺序vector<int> initialOrder;string line;getline(cin, line);stringstream ss(line);int num;while(ss >> num){initialOrder.push_back(num);}// 读取目标排列顺序vector<int> targetOrder;getline(cin, line);stringstream ss2(line);while(ss2 >> num){targetOrder.push_back(num);}int n = initialOrder.size();int groupCount = n / 3;// 创建组映射数组,将学生编号映射到组号vector<int> groupMapping(n+1, 0);for(int i=0;i<n;i++){groupMapping[targetOrder[i]] = i / 3;}// 将初始顺序转换为组号数组vector<int> groupOrder(n, 0);for(int i=0;i<n;i++){groupOrder[i] = groupMapping[initialOrder[i]];}// 创建组位置数组vector<vector<int>> groupPositions(groupCount, vector<int>());for(int i=0;i<n;i++){groupPositions[groupOrder[i]].push_back(i);}int minimumMoves = 0;// 遍历每个组,计算调整次数for(auto &positions : groupPositions){if(positions.size() == 3){if(positions[1] - positions[0] > 1 || positions[2] - positions[1] > 1){minimumMoves++;}}else if(positions.size() == 2){if(positions[1] - positions[0] > 2){minimumMoves++;}}else if(positions.size() == 1){minimumMoves += 2;}}// 计算组间的交错情况unordered_set<int> encounteredGroups;int overlapAdjustments = 0;for(auto &group : groupOrder){if(encounteredGroups.find(group) == encounteredGroups.end()){encounteredGroups.insert(group);}else{overlapAdjustments++;}}// 取最小调整次数minimumMoves = min(minimumMoves, overlapAdjustments);// 输出结果cout << minimumMoves;return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

相关文章:
华为OD机试 - 小朋友分组最少调整次数 - 贪心算法(Python/JS/C/C++ 2024 E卷 100分)
华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…...
数字农业与遥感监测平台
随着全球人口的增长和气候变化的挑战,农业的可持续发展变得尤为重要。数字农业作为现代农业发展的重要方向,正逐渐成为提高农业生产效率、保障粮食安全的关键手段。遥感技术作为数字农业的重要组成部分,通过监测作物生长状况、土壤湿度、病虫…...
2023年12月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析
一、单选题 1、下列程序运行的结果是?( ) print(hello) print(world) A.helloworld B.hello world C.hello world D.helloworld 正确答案:B 答案解析:本题考察的 Python 编程基础,print 在打印时…...
【优选算法】——双指针(下篇)!
🌈个人主页:秋风起,再归来~ 🔥系列专栏:C刷题算法总结 🔖克心守己,律己则安 目录 1、有效三角形的个数 2、查找总价值为目标值的两个商品 3、三数之和 4、四数之和 5、完结散花 1、有…...
C#中函数重载的说明
一.函数重载的基本概念 C# 中的函数重载是指在同一个类中定义多个同名的函数,但这些函数的参数类型、参数个数、参数顺序等不同,以便适应不同的调用需求,增加代码的兼容性。 二.函数重载的作用 2.1定义多个相类似的函数,减少函…...
图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网)
图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网)) 广度优先搜索理论基础bfs与dfs的对比(思维导图)&…...
源码编译方式安装htppd软件
一.源码编译安装httpd软件 1.安装阿帕奇的依赖,安装apr软件,阿帕奇正常运行的环境这个环境就是apr。 2.安装apr-util软件,主要提供针对apr环境的管理工具, 3.安装阿帕奇软件即httpd软件。 如上图所示,就是三个软件的…...
MES制造执行系统原型图动端 Axure原型 交互设计 Axure实战项目
MES制造执行系统原型移动端 Manufacturing Execution System prototype MES制造执行系统原型图移动端是专门为制造执行系统设计的移动端是一个可视化的设计。用于展示和演示该系统在移动设备上的功能和界面。通过原型图,可以清晰地了解制造执行系统在移动端的各个…...
flutter 仿淘宝推荐二级分类效果
先看效果 一开始 用的PageView 做的, 然后重写PageScrollPhysics一顿魔改, 最后发现还是有一些小bug。 后面又想到pageview 能做,listview肯定也能做,最后用ListView加GridView 把功能实现了。 listview 实现pageview 的分页滑动…...
报错 - LangChain AgentExecutor - ‘function‘ object has no attribute ‘get‘
使用 AgentExecutor 调用了使用两个 tool 的agent,报一下错误: 如果 agent 只使用 一个tool,没有报错 File "/Users/xx/miniconda3/envs/env1/lib/python3.11/site-packages/pydantic/_internal/_validators.py", line 44, in sequ…...
【DIY小记】通过降低电压和Process Lasso工具优化CPU超频表现
又到了创作纪念日,秉承着笔耕不辍的理念,笔者还是继续分享一下DIY日常。 在上一篇文章当中,笔者介绍了一些作为新手小白超频CPU和NVIDIA显卡的经验。今天又有了更新,笔者通过降低CPU工作电压,并且结合Process Lasso对…...
3、Docker搭建MQTT及Spring Boot 3.x集成MQTT
一、前言 本篇主要是围绕着两个点,1、Docker 搭建单机版本 MQTT(EMQX),2、Spring Boot 3.x 集成 MQTT(EMQX); 而且这里的 MQTT(EMQX)的搭建也只是一个简单的过程&#x…...
六种定时任务记录
1、java自带的Timer Timer是java中自带的类。 优点:使用简单,缺点是当添加并执行多个任务时,前面任务的执行用时和异常将影响到后面任务。 Timer timer new Timer();timer.schedule(new TimerTask() {int i 0;Overridepublic void run() …...
Dos下编译环境搭建和C运行程序生成
文章目录 前言一、需要准备的Tool二、搭建步骤 前言 因为工作需要,需要搭建个Dos下的编译环境来进行Code App开发,如下记录下搭建过程。 一、需要准备的Tool 编译环境:Win10/win11 编译工具: DOSBox0.74 Turboc2.7z 二、搭建步骤 1.双击压…...
【MySQL】入门篇—SQL基础:数据查询语言(DQL):复杂的SELECT语句
在实际应用中,复杂的SELECT语句可以帮助我们从多个表中提取相关信息,进行数据分析,生成报告,甚至进行数据挖掘。 掌握复杂的SELECT语句对于数据分析师、数据库管理员和开发者来说是必不可少的技能。 应用场景: 多表查…...
Appium环境搭建、Appium连接真机
文章目录 一、安装Android SDK二、安装Appium-desktop三、安装Appium Inspector 一、安装Android SDK 首先需要安装jdk,这里就不演示安装jdk的过程了 SDK下载地址:Android SDK 下载 1、点击 Android SDK 下载 -> SKD Tools 2、选择对应的版本进行下…...
【X线源】关于滨松MCS2软件的说明
【X线源】关于滨松MCS2软件的说明 1.软件背景2.MCS2界面3.MCS2操作4.常见问题 1.软件背景 滨松为了方便客户将滨松MFX集成进自己的系统,滨松提供了MFX二次开发相关的信息和Demo代码。参考博客说明: 【X线源】关于滨松MFX二次开发demo示例简介 https://…...
【深度学习代码调试2】环境配置篇(中) -- 列出conda环境中所有env的pytorch版本
【深度学习代码调试2】环境配置篇(中) -- 列出conda环境中所有env的pytorch版本 写在最前面如何检查所有 Conda 环境中的 PyTorch 版本(并重点提示 PyTorch 1.7.1 版本)1. 列出所有 Conda 环境2. 检查每个环境中的 PyTorch 版本方…...
C语言运算符和表达式
1.C语言赋值运算符实例讲解 C 使用运算符(operator)来代表算术运算。例如,运算符可以使它两侧的值加在一起。如果您觉得术语“运算符”听起来比较奇怪,那么请您记住那些东西总得有个名称。与其被称之为“那些东西”或“数学符号”,被称之为“…...
RetinaNet 分类头和回归头的网络结构分析
RetinaNet 是由 Facebook AI Research(FAIR)在 2017 年提出的一种高效的一阶段(one-stage)目标检测算法。相比于两阶段(two-stage)方法,RetinaNet 通过引入 Focal Loss 解决了类别不平衡问题&am…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
