13.搬砖

目录

题目

Description

Input

Output

思路(归并排序)

具体步骤如下

C++整体代码(含详细注释)

归并排序总结

核心步骤

代码模板


题目

Description

小张在暑假时间来到工地搬砖挣钱。包工头交给他一项艰巨的任务,将一排砖头按照从低到高的顺序排好。可是小张的力量有限,每次只能交换相邻的两块砖头,请问他最少交换几次能够完成任务?

Input

第一行一个整数

n(1 \leq n \leq 300000 )

,表示砖头数量。
第二行

n

个整数

a_i(-1000000000 \leq a_i \leq 1000000000 )

,表示砖头的高度。

Output

一个整数,表示最少交换几次能够完成任务。

测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. 5↵
  2. 4 1 3 2 5↵
以文本方式显示
  1. 4↵
1秒64M0


思路(归并排序)

冒泡排序的时间复杂度是O(n^2),归并排序的时间复杂度是O(nlogn);
本题使用冒泡排序TLE(超时),因此考虑归并排序。
 

归并排序的思路是将数组划分为越来越小的子数组,然后不断将子数组合并成有序的数组。在合并的过程中,统计交换次数,即每次将右半区的元素插入到左半区时,左半区剩余的元素个数(即逆序数)为交换次数

通过归并排序的思路,可以保证最终的数组是有序的,并且交换次数是最少的。


具体步骤如下

1.首先,定义了一个merge函数,用于将两个有序的子数组合并成一个有序的数组。在合并的过程中,记录交换次数count,用来统计交换的次数。

//归并两个有序数组 
void merge(vector<long long>& h, int left, int mid, int right, long long& count) {vector<long long> tempArr(right - left + 1);//分配一个临时数组int l_pos = left;int r_pos = mid + 1;int pos = 0;while (l_pos <= mid && r_pos <= right) {if (h[l_pos] <= h[r_pos]) {//左半区第一个剩余元素更小tempArr[pos++] = h[l_pos++];}else {//右半区第一个剩余元素更小tempArr[pos++] = h[r_pos++];count += mid - l_pos + 1; // 更新交换次数}}//合并左半区剩余元素while (l_pos <= mid)tempArr[pos++] = h[l_pos++];//合并右半区剩余元素while (r_pos <= right)tempArr[pos++] = h[r_pos++];//把临时数组中合并后的元素复制回原来的数组for (int i = 0; i < pos; i++) {h[left + i] = tempArr[i];}
}

2.然后,定义了一个mergeSort函数,用于对数组进行归并排序。在归并排序的过程中,将数组不断划分为两个子数组,然后分别对子数组进行递归排序,最后再将两个有序的子数组合并成一个有序的数组。

//归并排序
void mergeSort(vector<long long>& h, int left, int right, long long& count) {if (left >= right) {//如果左区间大于右区间或者只有一个元素时,就不需要继续划分//如果只有一个元素,本生就是有序的,只需要被归并即可return;}//找中间点int mid = (left + right) / 2;//递归划分左半区mergeSort(h, left, mid, count);//递归划分右半区mergeSort(h, mid + 1, right, count);//合并已经排序的部分merge(h, left, mid, right, count);
}

3.在主函数中,首先读取输入的砖头数量n和砖头的高度数组h。然后定义一个变量count来记录交换次数。接着调用mergeSort函数对数组h进行归并排序,并将交换次数保存在count中。

最后,输出count,即为完成任务所需的最少交换次数。

int main() {int n;cin >> n;vector<long long> h(n);for (int i = 0; i < n; i++) {cin >> h[i];}long long count = 0;mergeSort(h, 0, h.size() - 1, count);cout << count << endl;return 0;
}

C++整体代码(含详细注释)

#include <iostream>
#include <algorithm>
#include <vector> using namespace std;//归并两个有序数组 
void merge(vector<long long>& h, int left, int mid, int right, long long& count) {vector<long long> tempArr(right - left + 1);//分配一个临时数组int l_pos = left;int r_pos = mid + 1;int pos = 0;while (l_pos <= mid && r_pos <= right) {if (h[l_pos] <= h[r_pos]) {//左半区第一个剩余元素更小tempArr[pos++] = h[l_pos++];}else {//右半区第一个剩余元素更小tempArr[pos++] = h[r_pos++];count += mid - l_pos + 1; // 更新交换次数}}//合并左半区剩余元素while (l_pos <= mid)tempArr[pos++] = h[l_pos++];//合并右半区剩余元素while (r_pos <= right)tempArr[pos++] = h[r_pos++];//把临时数组中合并后的元素复制回原来的数组for (int i = 0; i < pos; i++) {h[left + i] = tempArr[i];}
}//归并排序
void mergeSort(vector<long long>& h, int left, int right, long long& count) {if (left >= right) {//如果左区间大于右区间或者只有一个元素时,就不需要继续划分//如果只有一个元素,本生就是有序的,只需要被归并即可return;}//找中间点int mid = (left + right) / 2;//递归划分左半区mergeSort(h, left, mid, count);//递归划分右半区mergeSort(h, mid + 1, right, count);//合并已经排序的部分merge(h, left, mid, right, count);
}int main() {int n;cin >> n;vector<long long> h(n);for (int i = 0; i < n; i++) {cin >> h[i];}long long count = 0;mergeSort(h, 0, h.size() - 1, count);cout << count << endl;return 0;
}

归并排序总结

归并排序的核心是将一个未排序的数组逐步划分为越来越小的子数组,然后将这些子数组合并成一个有序的数组。

核心步骤

  1. 分割:将未排序的数组划分为两个子数组,分别对左右两个子数组进行递归地分割,直到每个子数组只包含一个元素或为空。

  2. 合并:将两个有序的子数组合并成一个有序的数组。在合并的过程中,比较左右两个子数组的元素,将较小(或较大)的元素放入临时数组中,直到其中一个子数组的元素全部放入临时数组中。然后将剩余的另一个子数组的元素依次放入临时数组中。

  3. 复制:将临时数组中的元素复制回原来的数组。

通过不断地递归分割和合并,最终可以得到一个完全有序的数组。

归并排序的核心思想是分治法,将一个大问题拆分为若干个小问题,然后分别解决这些小问题,最后将解决好的小问题合并成一个整体解决方案。在归并排序中,每次合并两个有序的子数组时,都能保证合并后的数组仍然是有序的,通过不断地合并,最终可以得到一个完全有序的数组。

代码模板

#include <iostream>
#include <vector>using namespace std;// 合并两个有序的子数组
void merge(vector<int>& nums, int left, int mid, int right) {int n1 = mid - left + 1; // 左子数组的长度int n2 = right - mid; // 右子数组的长度// 创建临时数组来存储合并后的结果vector<int> temp(n1 + n2);int i = left; // 左子数组的起始索引int j = mid + 1; // 右子数组的起始索引int k = 0; // 临时数组的索引// 将两个子数组中的元素按照从小到大的顺序放入临时数组中while (i <= mid && j <= right) {if (nums[i] <= nums[j]) {temp[k++] = nums[i++];} else {temp[k++] = nums[j++];}}// 将左子数组中剩余的元素放入临时数组中while (i <= mid) {temp[k++] = nums[i++];}// 将右子数组中剩余的元素放入临时数组中while (j <= right) {temp[k++] = nums[j++];}// 将临时数组中的元素复制回原数组for (int p = 0; p < n1 + n2; p++) {nums[left + p] = temp[p];}
}// 归并排序
void mergeSort(vector<int>& nums, int left, int right) {if (left >= right) {return;}int mid = left + (right - left) / 2; // 找到数组的中间位置// 递归地对左右两个子数组进行归并排序mergeSort(nums, left, mid);mergeSort(nums, mid + 1, right);// 合并两个有序的子数组merge(nums, left, mid, right);
}int main() {int n;cin >> n;vector<int> nums(n);for (int i = 0; i < n; i++) {cin >> nums[i];}mergeSort(nums, 0, n - 1);// 输出排序后的数组for (int i = 0; i < n; i++) {cout << nums[i] << " ";}cout << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/110553.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【进阶篇】MySQL 存储引擎详解

文章目录 0.前言1.基础介绍2.1. InnoDB存储引擎底层原理InnoDB记录存储结构和索引页结构InnoDB记录存储结构&#xff1a;InnoDB索引页结构&#xff1a; 3. MVCC 详解3.1. 版本号分配&#xff1a;3.2. 数据读取&#xff1a;3.3. 数据写入&#xff1a;3.4. 事务隔离级别&#xff…

OpenHarmony设备截屏的5种方式

本文转载自《OpenHarmony设备截屏的5种方式 》&#xff0c;作者westinyang 目录 方式1&#xff1a;系统控制中心方式2&#xff1a;OHScrcpy投屏工具方式3&#xff1a;DevEcoStudio截屏功能方式4&#xff1a;hdc shell snapshot_display方式5&#xff1a;hdc shell wukong持续关…

alpha shapes提取二维点云边界(附python代码)

alpha shapes算法是一种简单、有效的快速提取边界点算法。其克服了点云边界点形状影响的缺点,可快速准确提取边界点,其原理如下: 如下图所示,对于任意形状的平面点云,若一个半径为a的圆,绕其进行滚动。若滚动圆半径a足够小时,则点云中每一点均为边界点;若适当增大到一…

linux内网yum源服务器搭建

1.nginx: location / {root /usr/local/Kylin-Server-V10-SP3-General-Release-2303-X86_64;autoindex on;autoindex_localtime on;autoindex_exact_size off; } 注:指定到镜像的包名 2.修改yum源地址 cd /etc/yum.repos.d/vim kylin_x86_64.repo 注: --enabled设置为1 3.重…

java内存分区

按照垃圾收集&#xff0c;将 Java 堆划分为**新生代 &#xff08;Young Generation&#xff09;和老年代&#xff08;Old Generation&#xff09;**两个区域&#xff0c; 新生代存放存活时间短的对象&#xff0c;而每次回收后存活的少量对象&#xff0c;将会逐步晋升到老年代中…

Qt:界面实时响应鼠标拖动绘制

采用双缓冲实现界面实时响应鼠标的拖动绘制。 思想如下&#xff1a;首先需要两张画布pix和tempPix&#xff0c;他们都是QPixmap实例&#xff1b;pix用来保存初始界面或上一阶段以完成的绘制&#xff1b;tempPix用来作为鼠标拖动时的实时界面绘制&#xff1b;当鼠标左键按下后拖…

Ubuntu 22.04.3 LTS 维护更新发布

近日消息&#xff0c;Canonical 今天发布了代号为 Jammy Jellyfish、长期支持的 Ubuntu 22.04 第 3 个维护版本更新&#xff0c;距离上个版本相隔 6 周时间。 Ubuntu 22.04.3 LTS 最大的亮点在于内核升级到 Linux Kernel 6.2&#xff0c;此外 Mesa 图形堆栈也升级到 23.0.4 版…

记一种不错的缓存设计思路

之前与同事讨论接口性能问题时听他介绍了一种缓存设计思路&#xff0c;觉得不错&#xff0c;做个记录供以后参考。 场景 假设有个以下格式的接口&#xff1a; GET /api?keys{key1,key2,key3,...}&types{1,2,3,...} 其中 keys 是业务主键列表&#xff0c;types 是想要取到的…

呈现数据的精妙之道:选择合适的可视化方法

在当今数据时代&#xff0c;数据可视化已成为理解和传达信息的重要手段。然而&#xff0c;选择适合的数据可视化方法对于有效地呈现数据至关重要。不同的数据和目标需要不同的可视化方法&#xff0c;下面我们将探讨如何选择最佳的数据可视化方法来呈现数据。 1. 理解数据类型&a…

构建安全可信、稳定可靠的RISC-V安全体系

安全之安全(security)博客目录导读 2023 RISC-V中国峰会 安全相关议题汇总 说明&#xff1a;本文参考RISC-V 2023中国峰会如下议题&#xff0c;版权归原作者所有。

OpenCV 没有xfeatures2d解决方法

运行程序出现错误——无法打开包括文件: “opencv2/xfeatures2d.hpp”: No such file or directory 参考&#xff1a;博主1,博主2 从该链接下载与opencv版本一致的opencv_contrib&#xff0c;我安装的opencv是3.4.15&#xff0c;下载了opencv_contrib-3.4。 下面代码可以查看…

NetMarvel机器学习促广告收益最大化,加速获客

游戏出海的竞争日益激烈&#xff0c;这并非空穴来风。 从2021年第一季度至2022年第四季度&#xff0c;iOS平台的CPI增长了88%&#xff0c;意味着厂商需要花费近两倍的钱才能获取一个新用户。与此同时数据隐私政策持续收紧&#xff0c;更加提高了营销成本。 在成本高涨的当下&…

替代LT8711龙讯替代RTD2172 CS5265中文规格书4K60HZ转接线 设计Type-C转HDMI2.0高清投屏方案

龙迅LT8711是一款Type-C/DP1.2 to HDMI2.0方案芯片&#xff0c;北京集睿致远&#xff08;ASL&#xff09;推出的CS5265可以完全代替LT8711UX&#xff0c;封装尺寸比LT8711UX小的同时&#xff0c;CS5265的芯片集成度高&#xff0c;内置MCU&#xff0c;内置lLDO等&#xff0c;CS5…

无涯教程-Android - 系统架构

Android操作系统是一堆软件组件&#xff0c;大致分为五个部分和四个主要层&#xff0c;如体系结构图中所示。 Linux内核 底层是Linux-Linux 3.6&#xff0c;带有大约115个补丁&#xff0c;这在设备硬件之间提供了一定程度的抽象&#xff0c;并且包含所有必需的硬件驱动程序&am…

【PLSQL】PLSQL基础

文章目录 一&#xff1a;记录类型1.语法2.代码实例 二&#xff1a;字符转换三&#xff1a;%TYPE和%ROWTYPE1.%TYPE2.%ROWTYPE 四&#xff1a;循环1.LOOP2.WHILE&#xff08;推荐&#xff09;3.数字式循环 五&#xff1a;游标1.游标定义及读取2.游标属性3.NO_DATA_FOUND和%NOTFO…

Rancher2.5.9版本证书更新

一、环境 主机名IP地址操作系统rancher版本K8s-Master192.168.10.236Centos 72.5.9 二、更新证书 1、查看当前证书到期时间 2、进行证书轮换 [rootK8s-Master ~]# docker ps |grep rancher/rancher d581da2b7c4e rancher/rancher:v2.5.9 &q…

ISO 22737-2021预定轨迹低速自动驾驶系统-系统要求、性能要求和性能测试规范(中文全文版)

简介 自动驾驶系统的发展导致了人员、货物和服务运输方式的转变。其中一种新的运输方式是低速自动驾驶(LSAD)系统,它在预定的路线上运行。LSAD系统将被用于最后一英里的运输、商业区的运输、商业或大学校园区以及其他低速环境的应用。 由LSAD系统驾驶的车辆(可以包括与基…

【C语言基础】数据输入输出

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

Spring Security存在认证绕过漏洞 CVE-2021-22096

文章目录 0.前言1.参考文档2.基础介绍漏洞影响范围&#xff1a;官方说明&#xff1a;修复版本&#xff1a;漏洞利用步骤&#xff1a;修复方式&#xff1a; 3.解决方案 0.前言 背景&#xff1a;项目被扫到Spring Boot 的漏洞&#xff0c;严格的说应该是Spring Security 组件的漏…

地下水质分析积分球

我国的河流水资源相当丰富&#xff0c;河川径流总量历年来位居世界第三&#xff0c;年均达到了27000亿m。但经济快速发展的同时对河流水资源产生了一定的负面影响&#xff0c;河流水质污染和富营养化的现象偶有发生&#xff0c;在对我国七大水系216条河流503个主要断面进行监测…