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

华为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卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…...

数字农业与遥感监测平台

随着全球人口的增长和气候变化的挑战&#xff0c;农业的可持续发展变得尤为重要。数字农业作为现代农业发展的重要方向&#xff0c;正逐渐成为提高农业生产效率、保障粮食安全的关键手段。遥感技术作为数字农业的重要组成部分&#xff0c;通过监测作物生长状况、土壤湿度、病虫…...

2023年12月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析

一、单选题 1、下列程序运行的结果是&#xff1f;&#xff08; &#xff09; print(hello) print(world) A.helloworld B.hello world C.hello world D.helloworld 正确答案&#xff1a;B 答案解析&#xff1a;本题考察的 Python 编程基础&#xff0c;print 在打印时…...

【优选算法】——双指针(下篇)!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~ &#x1f525;系列专栏&#xff1a;C刷题算法总结 &#x1f516;克心守己&#xff0c;律己则安 目录 1、有效三角形的个数 2、查找总价值为目标值的两个商品 3、三数之和 4、四数之和 5、完结散花 1、有…...

C#中函数重载的说明

一.函数重载的基本概念 C# 中的函数重载是指在同一个类中定义多个同名的函数&#xff0c;但这些函数的参数类型、参数个数、参数顺序等不同&#xff0c;以便适应不同的调用需求&#xff0c;增加代码的兼容性。 二.函数重载的作用 2.1定义多个相类似的函数&#xff0c;减少函…...

图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网)

图论day56|广度优先搜索理论基础 、bfs与dfs的对比&#xff08;思维导图&#xff09;、 99.岛屿数量&#xff08;卡码网&#xff09;、100.岛屿的最大面积&#xff08;卡码网&#xff09;&#xff09; 广度优先搜索理论基础bfs与dfs的对比&#xff08;思维导图&#xff09;&…...

源码编译方式安装htppd软件

一.源码编译安装httpd软件 1.安装阿帕奇的依赖&#xff0c;安装apr软件&#xff0c;阿帕奇正常运行的环境这个环境就是apr。 2.安装apr-util软件&#xff0c;主要提供针对apr环境的管理工具&#xff0c; 3.安装阿帕奇软件即httpd软件。 如上图所示&#xff0c;就是三个软件的…...

MES制造执行系统原型图动端 Axure原型 交互设计 Axure实战项目

MES制造执行系统原型移动端 Manufacturing Execution System prototype MES制造执行系统原型图移动端是专门为制造执行系统设计的移动端是一个可视化的设计。用于展示和演示该系统在移动设备上的功能和界面。通过原型图&#xff0c;可以清晰地了解制造执行系统在移动端的各个…...

flutter 仿淘宝推荐二级分类效果

先看效果 一开始 用的PageView 做的&#xff0c; 然后重写PageScrollPhysics一顿魔改&#xff0c; 最后发现还是有一些小bug。 后面又想到pageview 能做&#xff0c;listview肯定也能做&#xff0c;最后用ListView加GridView 把功能实现了。 listview 实现pageview 的分页滑动…...

报错 - LangChain AgentExecutor - ‘function‘ object has no attribute ‘get‘

使用 AgentExecutor 调用了使用两个 tool 的agent&#xff0c;报一下错误&#xff1a; 如果 agent 只使用 一个tool&#xff0c;没有报错 File "/Users/xx/miniconda3/envs/env1/lib/python3.11/site-packages/pydantic/_internal/_validators.py", line 44, in sequ…...

【DIY小记】通过降低电压和Process Lasso工具优化CPU超频表现

又到了创作纪念日&#xff0c;秉承着笔耕不辍的理念&#xff0c;笔者还是继续分享一下DIY日常。 在上一篇文章当中&#xff0c;笔者介绍了一些作为新手小白超频CPU和NVIDIA显卡的经验。今天又有了更新&#xff0c;笔者通过降低CPU工作电压&#xff0c;并且结合Process Lasso对…...

3、Docker搭建MQTT及Spring Boot 3.x集成MQTT

一、前言 本篇主要是围绕着两个点&#xff0c;1、Docker 搭建单机版本 MQTT&#xff08;EMQX&#xff09;&#xff0c;2、Spring Boot 3.x 集成 MQTT&#xff08;EMQX&#xff09;&#xff1b; 而且这里的 MQTT&#xff08;EMQX&#xff09;的搭建也只是一个简单的过程&#x…...

六种定时任务记录

1、java自带的Timer Timer是java中自带的类。 优点&#xff1a;使用简单&#xff0c;缺点是当添加并执行多个任务时&#xff0c;前面任务的执行用时和异常将影响到后面任务。 Timer timer new Timer();timer.schedule(new TimerTask() {int i 0;Overridepublic void run() …...

Dos下编译环境搭建和C运行程序生成

文章目录 前言一、需要准备的Tool二、搭建步骤 前言 因为工作需要&#xff0c;需要搭建个Dos下的编译环境来进行Code App开发&#xff0c;如下记录下搭建过程。 一、需要准备的Tool 编译环境&#xff1a;Win10/win11 编译工具: DOSBox0.74 Turboc2.7z 二、搭建步骤 1.双击压…...

【MySQL】入门篇—SQL基础:数据查询语言(DQL):复杂的SELECT语句

在实际应用中&#xff0c;复杂的SELECT语句可以帮助我们从多个表中提取相关信息&#xff0c;进行数据分析&#xff0c;生成报告&#xff0c;甚至进行数据挖掘。 掌握复杂的SELECT语句对于数据分析师、数据库管理员和开发者来说是必不可少的技能。 应用场景&#xff1a; 多表查…...

Appium环境搭建、Appium连接真机

文章目录 一、安装Android SDK二、安装Appium-desktop三、安装Appium Inspector 一、安装Android SDK 首先需要安装jdk&#xff0c;这里就不演示安装jdk的过程了 SDK下载地址&#xff1a;Android SDK 下载 1、点击 Android SDK 下载 -> SKD Tools 2、选择对应的版本进行下…...

【X线源】关于滨松MCS2软件的说明

【X线源】关于滨松MCS2软件的说明 1.软件背景2.MCS2界面3.MCS2操作4.常见问题 1.软件背景 滨松为了方便客户将滨松MFX集成进自己的系统&#xff0c;滨松提供了MFX二次开发相关的信息和Demo代码。参考博客说明&#xff1a; 【X线源】关于滨松MFX二次开发demo示例简介 https://…...

【深度学习代码调试2】环境配置篇(中) -- 列出conda环境中所有env的pytorch版本

【深度学习代码调试2】环境配置篇&#xff08;中&#xff09; -- 列出conda环境中所有env的pytorch版本 写在最前面如何检查所有 Conda 环境中的 PyTorch 版本&#xff08;并重点提示 PyTorch 1.7.1 版本&#xff09;1. 列出所有 Conda 环境2. 检查每个环境中的 PyTorch 版本方…...

C语言运算符和表达式

1.C语言赋值运算符实例讲解 C 使用运算符(operator)来代表算术运算。例如&#xff0c;运算符可以使它两侧的值加在一起。如果您觉得术语“运算符”听起来比较奇怪&#xff0c;那么请您记住那些东西总得有个名称。与其被称之为“那些东西”或“数学符号”&#xff0c;被称之为“…...

RetinaNet 分类头和回归头的网络结构分析

RetinaNet 是由 Facebook AI Research&#xff08;FAIR&#xff09;在 2017 年提出的一种高效的一阶段&#xff08;one-stage&#xff09;目标检测算法。相比于两阶段&#xff08;two-stage&#xff09;方法&#xff0c;RetinaNet 通过引入 Focal Loss 解决了类别不平衡问题&am…...

别再把FastAPI路由和挂载搞混了!一张图讲清`mount`与子应用的应用场景

FastAPI路由与挂载深度解析&#xff1a;如何为模块化开发选择最佳方案 在构建现代Web应用时&#xff0c;模块化设计已成为提升可维护性和团队协作效率的关键策略。FastAPI作为Python生态中最受欢迎的异步框架之一&#xff0c;提供了两种截然不同的模块化方案&#xff1a;APIRo…...

OpenFly实战:如何用无人机视觉语言导航工具链快速生成10万条训练数据

OpenFly实战&#xff1a;无人机视觉语言导航数据生成的10倍效率革命 当无人机开始理解人类语言指令时&#xff0c;一场人机交互的革命正在悄然发生。去年在深圳某科技园区&#xff0c;一组工程师仅用72小时就完成了过去需要三个月的数据采集工作——他们使用的秘密武器正是Open…...

OpCore Simplify:智能高效的OpenCore EFI配置工具技术指南

OpCore Simplify&#xff1a;智能高效的OpenCore EFI配置工具技术指南 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify OpCore Simplify是一款专为简化…...

Qwen3-ForcedAligner计算机网络应用:分布式语音标注系统

Qwen3-ForcedAligner计算机网络应用&#xff1a;分布式语音标注系统 1. 为什么需要分布式语音标注系统 语音数据标注是构建高质量语音识别系统的基石&#xff0c;但传统标注方式正面临三重困境。想象一下&#xff0c;一个语音技术团队每天要处理上千小时的方言录音、会议对话…...

Windows 10下ISE14.7与Modelsim 10.1c联合安装避坑指南(附完整破解流程)

Windows 10下ISE14.7与Modelsim 10.1c联合安装全流程解析 对于FPGA开发者而言&#xff0c;一套稳定的EDA环境是高效工作的基础。本文将详细介绍如何在Windows 10 64位系统中完成ISE Design Suite 14.7与Modelsim SE 10.1c的联合安装配置&#xff0c;特别针对安装过程中可能遇到…...

【2026年6月最新】英语四级历年真题及答案解析PDF电子版(2015-2025年12月)

2026年6月全国大学英语四级考试安排2026年上半年全国大学英语四级考试&#xff08;CET4&#xff09;定于6月13日举行。2025年12月四级真题资料包提供2025年12月英语四级考试全套备考资料&#xff1a;完整版考试真题试卷详细答案解析高清听力音频MP3文件PDF电子版文档&#xff0…...

如何通过铜钟音乐重拾纯粹听歌的乐趣:一个零干扰的Web音乐解决方案

如何通过铜钟音乐重拾纯粹听歌的乐趣&#xff1a;一个零干扰的Web音乐解决方案 【免费下载链接】tonzhon-music 铜钟 (Tonzhon.com): 免费听歌; 没有直播, 社交, 广告, 干扰; 简洁纯粹, 资源丰富, 体验独特&#xff01;(密码重置功能已回归) 项目地址: https://gitcode.com/G…...

PyCharm运行YOLOv8报错:onnx版本冲突的终极解决方案(附详细步骤)

PyCharm运行YOLOv8报错&#xff1a;onnx版本冲突的终极解决方案&#xff08;附详细步骤&#xff09; 当你在PyCharm中尝试将YOLOv8模型导出为ONNX格式时&#xff0c;突然弹出一条令人头疼的错误信息&#xff1a;module onnx has no attribute __version__。这就像在高速公路上…...

5个核心技巧:开源上采样工具OptiScaler的游戏优化实战指南

5个核心技巧&#xff1a;开源上采样工具OptiScaler的游戏优化实战指南 【免费下载链接】OptiScaler DLSS replacement for AMD/Intel/Nvidia cards with multiple upscalers (XeSS/FSR2/DLSS) 项目地址: https://gitcode.com/GitHub_Trending/op/OptiScaler OptiScaler作…...

「理」的征程(C++引入2——变量、运算与赋值(初步)(上))

在上一篇博文中&#xff0c;我教给大家了C的基础知识——输出&#xff0c;那么今天&#xff0c;让我们迈出踏入C殿堂的第二步——变量、运算与赋值。&#xff08;虽然说这篇文章好像只讲了变量&#xff09;&#xff08;P.S.我在学并查集的时候发现了一个非常棒的博文&#xff0…...