华为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…...

app测试有哪些内容?广东深圳软件测试机构推荐
随着智能手机的普及,手机应用app越来越多,因此,企业为了更好的保证用户留存率,开发完app之后必须进行app测试。一个成功的app,软件测试是必不可少的一步,那么app测试需要进行哪些测试内容呢?深圳又有哪些靠…...

新乡医学院第一附属医院启动巨额医疗设备整体维保招标
鉴于项目本身金额巨大,又恰逢省委巡视组进驻期间,该项目备受瞩目,在业内和省内医疗圈引起了极大轰动。全国影响力最大、实力最强的企业全部参与其中,民营企业上海柯渡医疗、上海昆亚医疗以其创新的服务模式和高效的管理机制备受关注;央企通用技术集团凯思轩达医疗科技凭借雄厚的…...

Linux——综合实用操作
目录 IP与主机 ping命令 wget命令 curl命令 端口:设备与外界通讯交流的出入口 进程管理 Linux top命令Windows 任务管理器 磁盘信息监控 df iostat 网络状态监控 sar -n DEV命令 环境变量 上传,下载 压缩 解压tar,zipÿ…...

一个Idea:爆改 T480
爆改 T480 准备大改 T480,家里有一台闲置很久的 T480,不舍得扔,打算升级一下。看了几位up主的视频后,决定动手改造。 计划如下 网卡:加装4G网卡硬盘:更换为 1T 的 NVMe 2280 固态硬盘内存:升…...

网络编程(21)——通过beast库快速实现http服务器
目录 二十一、day21 1. 头文件和作用域重命名 2. reponse时调用的一些函数 3. http_connection a. 构造函数 b. start() c. process_request() d. create_response() e. create_post_response() f. write_response() 4. Server 5. 主函数 6. 测试 1)测…...

Logback
Logback 简介 SpringBoot 内置日志框架 用来自定义控制台日志输出样式、生成日志文件 使用 由于是内置所以不需要引入,稍加配置就可以直接使用。 内置源头查看 配置application.yml # 日志配置 logging:level:com.ruoyi: logging.levelorg.springframework: war…...

Sub - Adjacent Transformer — 对AT的有趣改进
出处:IJCAI 2024 未开源,链接貌似是:jackyue1994/Sub-Adjacent-Transformer (github.com) 贡献:1. 提出:基于 “次邻域” 及 “注意力贡献” 的注意力学习机制,以增强异常、正常的区分;2. 首次…...

『Mysql集群』Mysql高可用集群之主从复制 (一)
Mysql主从复制模式 主从复制有一主一从、主主复制、一主多从、多主一从等多种模式. 我们可以根据它们的优缺点选择适合自身企业情况的主从复制模式进行搭建 . 一主一从 主主复制 (互为主从模式): 实现Mysql多活部署 一主多从: 提高整个集群的读能力 多主一从: 提高整个集群的…...

PHP获取图片属性(size, width, 和 height)的函数
在PHP中,要获取图片的尺寸(宽度和高度),你可以使用 getimagesize() 函数。这个函数不仅返回图片的宽度和高度,还返回图片的类型和MIME类型等信息。 以下是 getimagesize() 函数的基本用法: <?php /…...

MySQL启动失败解决方案
目录 引言 一、查看/启动mysql服务的两种方式 方法一: 方法二: 二、修改mysql服务启动路径的地址 三、"my.ini"文件的使用 设置my.ini文件的路径 给出一个使用my.ini文件的小例子 引言 造成启动闪退\失败的原因我仅仅以个人查询的一下博…...