高级堆排序

    今天在一个OJ上做了一个叫“Advanced Heap Sort”的题,题的解决算法没什么难的,但是对时间复杂度有要求,用正常的算法实现,都会超时,所以我就把这个题拿过来分享一下。


问题:

题目内容:
有两个序列S1和S2,各有N个元素。当我们在S1,S2各取一个数字时,总共会有N*N这么多可能的”和”(sum)。请找出这N*N这么多和里最小的N个值,并将它们加总后输出。输入格式:
只有一笔测资。测试资料第一行为一个正整数N。第二行有N个数字,以空白隔开,代表序列S1。第二行有N个数字,以空白隔开,代表序列S2。数字范围:
0 < N < 10000输出格式:
输出一行,N个最小的可能的和的加总。输入样例:
5
1 3 5 7 9
2 4 6 8 10输出样例:
27时间限制:100ms内存限制:128000kb


算法分析:

    这个题目既然是要求用堆排序,所以首先想到的时,建立一个N²的数组,通过两层循环,将所有的结果和填写到N²的大数组中,然后通过最小堆排序,将前N个进行和运算就可以了。但是这个题N的范围到10000,所以堆的大小是100000000,那么这个算法的时间复杂度就是O(n²)+ O(nlogN)+ O(nlogN) + O(n),可见时间复杂度和空间复杂度都很高,不能满足题目要求。

    所以,这里需要先将两个数列时行从小到大的排序,然后,建立一个N大的固定的堆,先填入N的数,并经进行最大堆排序,排序完成后,结果也就出来了。这里还有一个关键就是往堆里插入的值,原来是要插入N²个,因为现在将两个数列进行了从大到小的排序,所以满足插入的数列为:从第一个数组元素到(N/1) + (N/2) + (N/3) + .... + (N/N)  【因为A[1] + B[i], 0 <= i <= (N-1)/2都是答案的话(也就是前N小的),那么,A[0] + B[i]也是答案。因为A[0] + B[i] <= A[1] + B[i]】 ,通过这种方式进行时间复杂度的提升,再就是在进行两个数列的排序时,要使用归并法时行排序。

    这样的话,空间复杂度是N,时间复杂度是O(N log N) + O(log N) + O(NlogN * logN) + O(N log N),提升了不少,通过测试,完胜。

算法代码:

#include <stdio.h>int arrRst[10000]; //堆 
int arrMer[10000]; //归并排序的临时数组 
int n = 0; // 堆游标 //归并函数 
void merge(int *arr, int start, int mid, int end){int i, j, k;i = k = start;j = mid + 1;while((i <= mid) && (j <= end)){if(arr[i] <= arr[j]){arrMer[k++] = arr[i++];}else{arrMer[k++] = arr[j++];}}while(i <= mid){arrMer[k++] = arr[i++];}while(j <= end){arrMer[k++] = arr[j++];}for(i = start; i <= end; i++){arr[i] = arrMer[i];}
}//归并函数 
void mergeSort(int *arr, int start, int end){int mid;if(start < end){mid = (start + end) / 2;mergeSort(arr, start, mid);mergeSort(arr, mid + 1, end);merge(arr, start, mid, end);}
}void swap(x, y){int t;t = arrRst[x];arrRst[x] = arrRst[y];arrRst[y] = t;
}void shiftDown(int x){int t, flag = 0;while(x * 2 <= n && flag == 0){//左孩子 if(arrRst[x * 2] > arrRst[x]){t = x * 2;}else{t = x;}//右孩子if(x * 2 + 1 <= n){if(arrRst[x * 2 + 1] > arrRst[t]){t = x * 2 + 1;}} if(t == x){flag = 1;}else{swap(x, t);x = t;}}
}void creatHeap(){int i;for(i = n / 2; i >= 1; i--){shiftDown(i);}
}int main(){int arr[10000], arr2[10000];int N, sum = 0;int i, j;//输入 scanf("%d", &N);for(i = 1; i <= N; i++){scanf("%d", &arr[i]);}for(i = 1; i <= N; i++){scanf("%d", &arr2[i]);}//排序mergeSort(arr, 1, N);mergeSort(arr2, 1, N); for(i = 1; i <= N; i++){for(j = 1; j <= N / i; j++){//要插入的数据 if(n <= N - 1){ //只存放前N个 arrRst[++ n] = arr[i] + arr2[j];if(n == N){creatHeap();//对前N个建立最大堆 }	}else{if(arr[i] + arr2[j] < arrRst[1]){arrRst[1] = arr[i] + arr2[j];shiftDown(1);}}			}}for(i = 1; i <= n; i ++){sum += arrRst[i];}printf("%d", sum);return 0;
} 

博客名称:王乐平博客
博客地址:http://blog.lepingde.com
CSDN博客地址:http://blog.csdn.net/lecepin


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

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

相关文章

可以创建专业的客户端/服务器视频会议应用程序的音频和视频控件LEADTOOLS Video Conferencing SDK...

LEADTOOLS Video Streaming Module控件为您创建一个自定义的视频会议应用程序和工具提供所有需要的功能。软件开发人员可以使用Video Streaming Module SDK&#xff0c;通过一些不同的配置来创建一些客户端/服务器应用程序。例如&#xff0c;如果有一个服务器需要向多个客户端发…

Joseph Problem(解约瑟夫问题)

今天在一个OJ上做了一个Joseph Problem&#xff08;解约瑟夫问题&#xff09;的题&#xff0c;题目不难&#xff0c;直接用循环链表模拟实际操作即可完成&#xff0c;但是用此种方法的时间太长&#xff0c;超时&#xff0c;所以我就用了一个大家对这类问题比较常用的解法——数…

linux下mono的安装与卸载

我很遗憾的告诉你&#xff0c;这里没有安装&#xff0c;为什么标题里加入安装俩字呢&#xff0c;因为如果不加的话你会搜到这篇文章吗&#xff1f;哈哈&#xff01;别气馁&#xff0c;这里会给你些安装的tips&#xff01; 源码安装&#xff0c;git安装&#xff1a;建议安装路径…

繁体简体转换器 v 1.0

软件截图 软件说明 软件名称&#xff1a;繁体简体转换器 软件版本&#xff1a; 1.0 开发语言&#xff1a;易语言 软件说明&#xff1a;本软件主要是用于繁体中文转换为简体中文的工具&#xff0c;如果你想把转换后的文本用于MarkDown中&#xff0c;可以勾选“HTML转义”复选…

C#实现Combobox自动匹配字符

不多说了,如图,应客户要求,下拉框中需要自动匹配字符,可能有些人一早就对此很熟,但相对于我还是首次使用,还是花了一点时间,现记录下来,也希望能帮助大家更好的理解. 首先要设定Combobox的DropDownStyle属性为DropDown,而不是DropDownList.然后设定匹配数据源,有两种方法 第一种…

按键 使用WinHttp实现POST方式用户模拟登录网站

引言 这篇文章是我以前在一个论坛里写的&#xff0c;今天把这篇文章转移到这里。 文章主要介绍了如何模拟一个网站的登录。 这里使用的辅助工具是按键精灵&#xff0c;编程语言类似于VB。 实现步骤 第一步&#xff0c;获取登录地址 打开登录界面&#xff1a; 打开调试工…

华硕 RT-AC54U路由器固件功能说明

引言 华硕 RT-AC54U这款路由器固件&#xff0c;界面做的很不错&#xff08;起码比OpenWrt要好看&#xff09;&#xff0c;功能也比较强悍&#xff0c;但是对于刚入手这个固件的用户可能会对此固件的一些很好用的功能无从下手&#xff0c;所以这里我就写下了这个文章。 固件亮…

HTML5中类jQuery选择器querySelector的使用

为什么80%的码农都做不了架构师&#xff1f;>>> 简介 HTML5向Web API新引入了document.querySelector以及document.querySelectorAll两个方法用来更方便地从DOM选取元素&#xff0c;功能类似于jQuery的选择器。这使得在编写原生JavaScript代码时方便了许多。 用法 …

Find the Kth number(找第K大数)

题目再现 题目内容&#xff1a; 给定N个排序好的序列&#xff0c;每个序列内有M个数字。因此我们总共有N*M个数字&#xff0c;编号为1~N*M。 将N*M个数字排序后输出第K个数字是多少。Hint : 直接将N*M个数字做排序会超过时间限制。 Hint : 每次花O(N)的时间找一个数字&#xf…

[Android开源项目] GitHub开源项目总结 (转)

[Android开源项目] GitHub开源项目总结 GitHub开源项目android-styled-dialogshttp://neast.cn/forum.php?modviewthread&tid5376&fromuid5GitHub开源项目之changeloghttp://neast.cn/forum.php?modviewthread&tid5375&fromuid5GitHub开源项目之AppRaterhtt…

Species Tree(HashTable实现)

题目再现 题目内容&#xff1a; 给定一个物种演化图&#xff0c; 关系的表示方式如下&#xff1a; x y : 表示x为y的先祖。 一个物种只会有一个先祖&#xff0c; 一个先祖可以有很多个演化出来的物种&#xff0c; 请你找出每个问题询问物种的祖父物种(先祖的先祖)&#xff0c;…

苹果自己设计芯片,但是还是绕不过高通

苹果自己设计芯片&#xff0c;但是还是绕不过高通&#xff0c;目前高通是苹果的基带芯片供应商。不过基带芯片是指什么&#xff1f;苹果为何难以放弃高通芯片&#xff1f;最初苹果基带芯片供应商是博通公司&#xff0c;2011年初发布的CDMA版iPhone 4开始采用高通的基带芯片&…

Adjacent Node Sum(邻接表处理)

题目再现 题目内容&#xff1a; 给定一个节点有权重的图&#xff0c; 请你计算与一个节点相邻的所有节点的权重和。 节点编号为1~N。 每个节点的编号即为他的权重。输入格式: 只有一组测资。 第一行有三个数字&#xff0c;N、M、Q。 N表示这张图有多少节点&#xff0c; M表示这…

Smart Pointer

以下内容摘自《http://blog.csdn.net/asanscape/article/details/6084600》 Smart Pointer在初始化或释放等操作时&#xff0c;它们是一个对象&#xff0c;用点操作符&#xff0c;其他大部分操作则使用“->”操作符。 For example: _ConnectionPtr m_pConnection.CreateInst…

Maze(BFS处理)

题目再现 题目内容&#xff1a; 给你一个迷宫&#xff0c; S为起点&#xff0c;E为终点。 请你找出走出迷宫所需要花费的最短步数。 你只能往上下左右四个方向移动。输入格式: 第一行有一个数字T&#xff0c;代表有T组测资。 每组测资的第一行有两个数字R、C&#xff0c; 代表…

数据库笔记2:SQL运算符

SQL运算符实例代码教程 - 运算符是一个保留字或字符&#xff0c;主要用于在SQL语句的WHERE子句来执行&#xff0c;比较和算术运算等操作。 加法 -添加任一侧上的操作符的值SQL运算符是什么?运算符是一个保留字或字符&#xff0c;主要用于在SQL语句的WHERE子句来执行&#xff0…

Lotto(DFS处理)

题目再现 题目内容&#xff1a; 给定N个数字&#xff0c;再从中选定M个数字出来。 将每一种组合内的数字由小到大排列之后&#xff0c; 将所有组合按照字典序排列&#xff0c; 请你找出第X组的第Y个数字。 给定的数字为1~N。 范例1 (N,M,X,Y) (5,2,8,2) 所有组合按顺序排列为…

2016第七届蓝桥杯省赛C/C++ B组试题解析整理

引言 今天是蓝桥杯省赛举办的日子&#xff0c;是一个很激动人心的时刻&#xff0c;也是我第一次参加蓝桥杯&#xff0c;从上午9点到下午1点&#xff0c;做题时间历经4个小时&#xff0c;想想就过瘾。 下面整理一下这次比赛的题目。 *注&#xff1a;此处为了省事儿&#xff…

Linux 小知识翻译 - 「邮件服务器」

这次聊聊「邮件服务器」。 邮件服务器上通常会运行2个服务端软件&#xff0c;「SMTP服务器」和「POP服务器或者IMAP服务器」。 这2个东西&#xff0c;也许使用邮件客户端的人立马就明白了。因为设置邮件客户端的时候&#xff0c;需要指定「发信服务器」和「收信服务器」。 这2个…

终极结束进程方法API

引言 最近在机房里上课的时候&#xff0c;学生的电脑上都安装了相应的学生端软件&#xff0c;而这些软件并没法正常关闭&#xff0c;用任务管理器也无法关闭&#xff0c;下面我说一下如何用Windows API对这类顽固程序进行终结。 福利方法 由于相关方面的规定&#xff0c;这里…