OpenJudge | 置换选择排序

devtools/2024/10/10 7:19:08/

总时间限制: 1000ms 内存限制: 65536kB
描述
给定初始整数顺串,以及大小固定并且初始元素已知的二叉最小堆(为完全二叉树或类似完全二叉树,且父元素键值总小于等于任何一个子结点的键值),要求利用堆实现置换选择排序,并输出第一个顺串。例如给定初始顺串29,14,35,13,以及堆(记为16 19 31 25 21 56 40), 置换选择排序得到的第一个顺串为16 19 21 25。

在这里插入图片描述

输入

第一行包含两个整数,m为初始顺串的数的个数,n为二叉最小堆的大小
第二行包含m个整数,即初始顺串
第三行包含n个整数,即已经建好的堆的元素(有序,按照从堆顶到堆底,从左到右的顺序)

输出

输出包含一行,即第一个顺串。

样例输入

4 7
29 14 35 13
16 19 31 25 21 56 40

样例输出

16 19 21 25

思路

  1. 我们知道这是一个小根堆,堆顶元素是最小的,我们可以将堆顶元素取出,将其放入res数组中,然后将堆顶元素删除,注意,在这一步当中是不用关注初始化顺串的元素的。
  2. 然后将初始的顺串中的下一个元素放入堆中,然后调整堆,使其满足堆的性质。
    1. 如果初始的顺串被选中的元素比res数组中的最后一个元素大,那么就将这个元素放入堆中,然后调整堆;否则将这个元素先放入堆,然后与堆的最后一个元素交换,堆的大小减一,最后调整堆。
  3. 然后将堆顶元素取出,放入res数组中,然后将堆顶元素删除。
  4. 重复上述步骤2、3,直到堆为空或者初始顺串中的元素全部被替换。

看完原理,我们可以将代码分为两个部分,一个是调整堆的代码,一个是置换选择排序的代码。

代码解析

先说调整堆的代码:

void reflushHeap(int n) {int i = 1;while(2*i <= n || 2*i+1 <= n) {if(2*i <= n && 2*i+1 <= n) {if(ar[2*i] < ar[2*i+1]) {if(ar[i] > ar[2*i]) {swap(ar[i], ar[2*i]);i = 2*i;}} else {if(ar[i] > ar[2*i+1]) {swap(ar[i], ar[2*i+1]);i = 2*i+1;}}} else if(2*i <= n && 2*i+1 > n) {if(ar[i] > ar[2*i]) {swap(ar[i], ar[2*i]);i = 2*i;}	} else break;}
}

然后是置换选择排序的代码:
这代码在排除输入部分之后是这样的:

while(t--) {if(n <= 0) break;res.push_back(ar[1]);if(res.back() > in[j]) {ar[1] = in[j];swap(ar[1], ar[n]);--n;reflushHeap(n);} else {ar[1] = in[j];reflushHeap(n);}++j;
}

Code

#include <bits/stdc++.h>
#pragma GCC optimize(3,"Ofast","inline")
using namespace std;int ar[1024], in[1024];void reflushHeap(int n) {int i = 1;while(2*i <= n || 2*i+1 <= n) {if(2*i <= n && 2*i+1 <= n) {if(ar[2*i] < ar[2*i+1]) {if(ar[i] > ar[2*i]) {swap(ar[i], ar[2*i]);i = 2*i;}} else {if(ar[i] > ar[2*i+1]) {swap(ar[i], ar[2*i+1]);i = 2*i+1;}}} else if(2*i <= n && 2*i+1 > n) {if(ar[i] > ar[2*i]) {swap(ar[i], ar[2*i]);i = 2*i;}	} else break;}
}int main() {vector<int> res;ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int m, n, t, j = 1;cin >> m >> n;res.reserve(m);for(int i = 1; i <= m; ++i) {cin >> in[i];}for(int i = 1; i <= n; ++i) {cin >> ar[i];}t = m;while(t--) {if(n <= 0) break;res.push_back(ar[1]);if(res.back() > in[j]) {ar[1] = in[j];swap(ar[1], ar[n]);--n;reflushHeap(n);} else {ar[1] = in[j];reflushHeap(n);}++j;}for(auto i: res) {cout << i << " ";}
}

http://www.ppmy.cn/devtools/122024.html

相关文章

Spring Boot 基础入门指南

1. 什么是 Spring Boot&#xff1f; Spring Boot 是一个用于简化 Spring 应用程序开发的框架&#xff0c;旨在让开发者快速构建独立的、生产级的 Spring 应用。它提供了自动配置、嵌入式服务器和一系列开箱即用的功能&#xff0c;降低了应用程序的开发和部署难度。 2. Spring…

pytorch常用函数view、sum、sequeeze、cat和chunk

文章目录 view()函数sequeeze和unsequeezecat和chunk函数sum函数view()函数 view()相当于reshape、resize,重新调整Tensor的形状。 指定调整形状之后的维度import torch re = torch.tensor([1, 2, 3, 4, 5

LeetCode Hot100 | Day27 | 二叉树:二叉树的直径

LeetCode Hot100 | Day27 | 二叉树&#xff1a;二叉树的直径 主要学习内容&#xff1a; 二叉树深度求法 深度的 leftright1 得到的是从根结点到叶子结点的节点数量 543.二叉树的直径 [543. 二叉树的直径 - 力扣&#xff08;LeetCode&#xff09;](https://leetcode.cn/pro…

指针赋值or常数赋值

int main (){int a 10;int b ;b a;int *c &a;int *d c; } 常数 a,b赋值&#xff1a; 都是将存储的值&#xff08;10&#xff09;赋值给别人。 指针赋值也是类似的&#xff1a; 指针存储的值&#xff08;&a&#xff09;为地址&#xff0c;就是把c指向的地址赋值给…

MongoDB的查询/超详细/表达式符号

表达式符号列表 相等 $eq: 等于。 大于 $gt: 大于。 小于 $lt: 小于。 大于等于 $gte: 大于等于。 小于等于 $lte: 小于等于。 不等于 $ne: 不等于。 逻辑 AND $and: 逻辑与。 逻辑 OR $or: 逻辑或。 逻辑 NOR $nor: 逻辑非或。 逻辑 NOT $not: 逻辑非。 数组元素匹配 $all: 字…

计算机网络:物理层 —— 物理层下的传输媒体

文章目录 传输媒体导向性媒体同轴电缆双绞线光纤光纤分类中心波长光纤规格光纤的优缺点 非导向性媒体ISM 频段无线电波微波激光红外线可见光 传输媒体 传输媒体是计算机网络设备之间的物理通路&#xff0c;也称为传输介质或传输媒介&#xff0c;并不包含在计算机网络体系结构中…

GitHub入门与实践

1.GitHub入门与实践 参考资料&#xff1a;《GitHub入门与实践》 声明&#xff1a;本篇博客内容由笔者跟随该书进行实际操作并记录过程而来&#xff0c;该篇博客内容大部分来自上述提到的书中。 GitHub入门与实践 1.GitHub入门与实践1.1 对本地计算机里安装的 Git 进行设置1.2 …

(九)Shell 脚本(四):正则表达式、sed 和 awk 详解

一、正则表达式 正则表达式的作用和类型 作用&#xff1a;用于匹配满足特定条件的内容。类型&#xff1a;分为基础正则表达式和扩展正则表达式。 正则表达式的区别 基础正则表达式&#xff1a;使用 grep 或者 awk 对数据进行匹配、过滤和显示。扩展正则表达式&#xff1a;使用 …