超快速排序(蓝桥杯,归并排序,acwing)

news2025/2/23 23:16:39

题目描述:

在这个问题中,您必须分析特定的排序算法----超快速排序。

该算法通过交换两个相邻的序列元素来处理 n 个不同整数的序列,直到序列按升序排序。

对于输入序列 9 1 0 5 4,超快速排序生成输出 0 1 4 5 9

您的任务是确定超快速排序需要执行多少交换操作才能对给定的输入序列进行排序。

输入格式:

输入包括一些测试用例。

每个测试用例的第一行输入整数 n,代表该用例中输入序列的长度。

接下来 n 行每行输入一个整数 ai,代表用例中输入序列的具体数据,第 i 行的数据代表序列中第 i 个数。

当输入用例中包含的输入序列长度为 0 时,输入终止,该序列无需处理。

输出格式:

对于每个需要处理的输入序列,输出一个整数 op,代表对给定输入序列进行排序所需的最小交换操作数,每个整数占一行。

数据范围:

0≤n<500000
一个测试点中,所有 n 的和不超过 500000。
0≤ai≤999999999

输入样例:

5
9
1
0
5
4
3
1
2
3
0

输出样例:

6
0

分析步骤:

  第一:我们要交换相邻的数,交换的次数是前面比它大的数和后面比它小的数因为如果前面有比它大的数,那么它必定和前面的交换一次,使得前面大的数排到后面,同理可以知道比它小的数一定要和它交换到前面。这其实是一道求逆序对的题目。

             大家记住,相邻值交换,求逆序对就用归并排序

  第二:书写主函数,构建整体框架;

             将值输入进我们数组之中,输出归并排序的次数就可以

int main()
{
    int n ;
    while(cin>>n,n){
        for(int i = 0 ; i < n ; i ++){
            cin>>arr[i];
        }
        cout<<merge(0,n-1)<<endl;
    }
    
    
    return 0;
}

  第三:书写归并排序

             定义l , r为我们区间的边界,如果左边界大于等于右边界就返回,定义我们的 i 为左边界j 为 右边界的第一个所以为 mid+1 ,定义k 为新数组的第一个位置所以是0;

             继续归并排序直到将其分解为一个一个数将他们要更换的次数加起来,完成后返回res。

             进入while循环注意我们的条件左边区间不可以超过mid 右边区间不可以超过 r ;如果左边的区间小于等于右边的区间 则证明没有逆序对,则不需要更换位置,之接将其放入新数组中,如果左边区间的值 大于 右边区间的值 则res += mid - i + 1 ,因为逆序对的数量是mid - i + 1,res += mid - i + 1; 这句代码表示如果右半部分的元素 arr[j] 小于左半部分的元素 arr[i]那么它与左半部分的剩余元素都构成逆序对。通过计算 mid - i + 1,得到左半部分剩余元素的数量,即存在与 arr[j] 构成逆序对的数量。将这一数量累加到 res 中,以累计逆序对的总数。

         之后检查一下,左右两个部分有没有循环完毕,如果没有就让它继续循环,把数字放入新的数组之中。

         最后将tmp数组中刚刚存好的值,再次赋给arr数组。

LL merge(int l , int r){
     if(l >= r) return 0;
     int mid = (l+r) / 2;
     int i = l , j = mid + 1 , k =0;
     LL res=merge(l,mid)+merge(mid+1,r);
     while(i <= mid and j <= r){
         if(arr[i] <= arr[j]){
             tmp[k++] = arr[i++];
         }else{
             tmp[k++] = arr[j++];
           res += mid - i + 1;
         }
     }
    while(i <= mid){
        tmp[k++] = arr[i++];
    }
    while(j <= r){
        tmp[k++] = arr[j++];
    }
    for(int i = l , j = 0 ; i <= r ; j++ , i++){
       arr[i] = tmp[j];    
    }
    return res;
}

这两个图我给大家标出了i , j ,k的位置,大家可以好好注意注意,对于不理解的位置变化的那个式子,也可以根据这个图自己动手写一些,纸上得来终觉浅,得知此事要躬行

代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 5e5+10;
LL arr[N];
LL tmp[N];

// 定义归并排序函数,返回逆序对的数量
LL merge(int l , int r){
    if(l >= r) return 0; // 当序列长度为1时,逆序对数量为0
    
    int mid = (l+r) / 2; // 将数组分为两半
    
    // 递归地求解左半部分和右半部分的逆序对数量,并将结果相加
    LL res=merge(l,mid)+merge(mid+1,r);
    
    int i = l , j = mid + 1 , k =0; // i为左半部分的指针,j为右半部分的指针,k为临时数组的指针
    
    while(i <= mid and j <= r){
        if(arr[i] <= arr[j]){ // 当左半部分的元素小于等于右半部分的元素时,当前元素不会产生逆序对
            tmp[k++] = arr[i++]; // 将左半部分的元素放入临时数组中
        }else{
            tmp[k++] = arr[j++]; // 当右半部分的元素小于左半部分的元素时,当前元素会与左半部分的剩余元素构成逆序对
            res += mid - i + 1; // 将逆序对的数量累加上
        }
    }
    
    // 将剩余的元素放入临时数组中
    while(i <= mid){
        tmp[k++] = arr[i++];
    }
    while(j <= r){
        tmp[k++] = arr[j++];
    }
    // 将临时数组的元素复制回原数组
    for(int i = l , j = 0 ; i <= r ; j++ , i++){
        arr[i] = tmp[j];    
    }
    
    return res; // 返回逆序对的数量
}


int main()
{
    int n ;
    while(cin>>n,n){
        // 输入数组元素
        for(int i = 0 ; i < n ; i ++){
            cin >> arr[i];
        }
        // 调用归并排序函数,并输出逆序对的数量
        cout<< merge(0,n-1) << endl;
    }
    
    return 0;
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript基础知识2

求数组的最大值案例 let arr[2,6,1,7,400,55,88,100]let maxarr[0]let minarr[0]for(let i1;i<arr.length;i){max<arr[i]?maxarr[i]:maxmin>arr[i]?minarr[i]:min}console.log(最大值是&#xff1a;${max})console.log(最小值是&#xff1a;${min}) 操作数组 修改…

企业专业化管理金字塔:技能进阶与案例分析

在纷繁复杂的企业管理领域中&#xff0c;一套行之有效的管理技能体系对于企业的稳健发展至关重要。本文将深入探讨企业专业化管理金字塔的五个层次&#xff1a;基本的管理技能、业务操作管理技能、组织管理技能、组织开发技能以及管理转变技能&#xff0c;并结合实际案例&#…

Java后端八股------设计模式

Coffee可以设计成接口。 b

代码随想录算法训练营第27天|93.复原IP地址、78.子集、90.子集二

目录 一、力扣93.复原IP地址1.1 题目1.2 思路1.3 代码1.4 总结 二、力扣78.子集2.1 题目2.2 思路2.3 代码2.4 总结 三、力扣90.子集二3.1 题目3.2 思路3.3 代码3.4 总结 一、力扣93.复原IP地址 &#xff08;比较困难&#xff0c;做起来很吃力&#xff09; 1.1 题目 1.2 思路 …

30.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-数据搜索功能

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;29.数据推测功能…

解决MySQL “Lock wait timeout exceeded; try restarting transaction“ 错误

在处理MySQL数据库时&#xff0c;我们偶尔会遇到一个棘手的错误消息&#xff1a;“Lock wait timeout exceeded; try restarting transaction”。这通常表明我们的一个事务在尝试获取资源时被阻塞了太长时间。在并发环境中&#xff0c;多个事务同时竞争相同的资源可能会导致这种…

前端 - 基础 表单标签 -- 表单元素( input - type属性) 文本框和密码框

表单元素 &#xff1a; 在表单域中可以定义各种表单元素&#xff0c;这些表单元素就是允许用户在表单中输入或选择 的内容控件。 表单元素的外观也各不一样&#xff0c;有小圆圈&#xff0c;有正方形&#xff0c;也有方框&#xff0c;乱七八糟的&#xff0c;各种各样&#xf…

关系数据库:关系数据结构基础与概念解析

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

2024/03/19总结

算法&#xff1a; 简单的一个dfs就能过 ac: #include "iostream" #include "algorithm" #include "cstring" #include "queue" using std::cin; using std::cout; using std::endl; #define N 110 char a[N][N]; int abook[N][N]; i…

算法|基础算法|二分和双指针

数学与数论|二分 1.基础二分 2.双指针 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴水可以击穿顽石。 基础二分 模板 bool check(int x){/*...*/} …

spring suite搭建springboot操作

一、前言 有时候久了没开新项目了&#xff0c;重新开发一个新项目&#xff0c;搭建springboot的过程都有点淡忘了&#xff0c;所有温故知新。 二、搭建步骤 从0开始搭建springboot 1&#xff0e;创建work空间。步骤FileNewJava Working Set。 2.选择Java Working Set。 3.自…

Java八股文(RabbitMQ)

Java八股文のRabbitMQ RabbitMQ RabbitMQ RabbitMQ 是什么&#xff1f;它解决了哪些问题&#xff1f; RabbitMQ 是一个开源的消息代理中间件&#xff0c;用于在应用程序之间进行可靠的异步消息传递。 它解决了应用程序间解耦、消息传递、负载均衡、故障恢复等问题。 RabbitMQ …

SpringCloud Bus 消息总线

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第八篇&#xff0c;即介绍 Bus 消息总线。 二、概述 2.1 遗留的问题 在上一篇文章的最后&#xff0c;我…

Gradle v8.5 笔记 - 从入门到进阶(基于 Kotlin DSL)

目录 一、前置说明 二、Gradle 启动&#xff01; 2.1、安装 2.2、初始化项目 2.3、gradle 项目目录介绍 2.4、Gradle 项目下载慢&#xff1f;&#xff08;万能解决办法&#xff09; 2.5、Gradle 常用命令 2.6、项目构建流程 2.7、设置文件&#xff08;settings.gradle.…

15|BabyAGI:根据气候变化自动制定鲜花存储策略

一种新型的代理——Autonomous Agents&#xff08;自治代 理或自主代理&#xff09;&#xff0c; 在 LangChain 的代理、工具和记忆这些组件的支持下&#xff0c;它们能够在无需外部干预的情况下自主 运行&#xff0c;这在真实世界的应用中具有巨大的价值。 AutoGPT 它的主要…

晶圆制造过程中常用载具的类型

晶圆载具用于硅片生产、晶圆制造以及工厂之间晶圆的储存、传送、运输以及防护。晶圆载具种类很多,如FOUP用于晶圆制造工厂中晶圆的传送;FOSB用于硅片生产与晶圆制造工厂之间的运输;CASSETTE载具可用于工序间运送以及配合工艺使用。 OPEN CASSETTE OPEN CASSETTE主要在晶圆…

机器视觉系统选型-镜头基础知识

广角镜头&#xff1a;焦距小于标准焦距50mm的。例如&#xff1a;16mm 景深大&#xff0c;聚焦距离更近 远距照像镜头&#xff1a;焦距大于标准焦距50mm的。例如&#xff1a;75mm 景深浅&#xff0c;放大远距离物体 变焦镜头&#xff1a;镜头焦距可调节&#xff0c;焦距有范围&a…

JWT(跨域身份验证解决方案)

Json web token (JWT), 跨域身份验证解决方案,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于…

学习总结!

最近主要学习了java&#xff0c;题目的话就写了两道。 这道题目运用三维的bfs&#xff0c;第一次做时无从下手&#xff0c;原来可以利用三维数组&#xff08;第一次用三维数组&#xff09;可以解决这类问题&#xff0c;然后套bfs模板即可。 #include<iostream> #include…

Pandas:如何让你的代码性能飙升

在数据分析相关的工作中&#xff0c;Pandas无疑是一个强大的工具&#xff0c;它的易用性和灵活性广受青睐。然而&#xff0c;随着数据量的不断增长和计算需求的日益复杂&#xff0c;Pandas代码的性能问题也逐渐浮出水面。如何让Pandas代码运行得更快、更高效&#xff0c;成为了…