堆和堆排序
2014-04-26 17:58
183 查看
这个题大意是有一个数据结构支持两种操作A与Get操作,其中A
x表示插入x. Get i表示返回结构中的第i小的数.给你A和Get操作的顺序和参数,现在要你对每个Get输出值.
取前u(i)个数排序~
然后取第i个数~(i=1,2,3……)
后来发现可以用大顶堆和小顶堆做~
每次将u(i)个数存入小顶堆中~
取小顶堆堆顶元素存入大顶堆中~
删除堆顶元素~
将大顶堆堆顶元素存入小顶堆中删除堆定元素~
这样大顶堆中的元素个数不变~
总是最小的前i个~
题解:每次取第k小元素,k不断更新。使用两个堆,来完成。
小顶堆负责选出最小的元素,大顶堆负责选出k个元素中最大的元素,即第k小元素
大顶堆的堆顶元素始终小于小顶堆的堆顶元素,这样的话大顶堆中的所有元素都小于小顶堆中的元素,如果大顶堆中有k-1个元素,那么小顶堆的堆顶元素就是要找的
第k小 元素了
Sample Input
7 4 ( n,m,分别是a数组,u数组的元素个数)
3 1 -4 2 8 -1000 2 (a数组)
1 2 6 6 (数u[i]w为几就加到a几,然后输出第i 小的:输出数组a前1个第1小的,前两个第2小的,前6个第3小的,前6个第4小的)
Sample Output
3
3
1
2
大根堆分别有1、2、3、4个元素 3 ,3 1,3 1 -4 2 8 -1000,3 1 -4 2 8 -1000。。。。3,3 1,1 -4 -1000,1 -4 2 -1000。。。。_,1, -4 -1000,1 -4 -1000
小顶堆元素为 3,3,3 1 2 8,3 2 8 即负责选出最小元素
题外话丨分治法 直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。
x表示插入x. Get i表示返回结构中的第i小的数.给你A和Get操作的顺序和参数,现在要你对每个Get输出值.
取前u(i)个数排序~
然后取第i个数~(i=1,2,3……)
后来发现可以用大顶堆和小顶堆做~
每次将u(i)个数存入小顶堆中~
取小顶堆堆顶元素存入大顶堆中~
删除堆顶元素~
将大顶堆堆顶元素存入小顶堆中删除堆定元素~
这样大顶堆中的元素个数不变~
总是最小的前i个~
题解:每次取第k小元素,k不断更新。使用两个堆,来完成。
小顶堆负责选出最小的元素,大顶堆负责选出k个元素中最大的元素,即第k小元素
大顶堆的堆顶元素始终小于小顶堆的堆顶元素,这样的话大顶堆中的所有元素都小于小顶堆中的元素,如果大顶堆中有k-1个元素,那么小顶堆的堆顶元素就是要找的
第k小 元素了
Sample Input
7 4 ( n,m,分别是a数组,u数组的元素个数)
3 1 -4 2 8 -1000 2 (a数组)
1 2 6 6 (数u[i]w为几就加到a几,然后输出第i 小的:输出数组a前1个第1小的,前两个第2小的,前6个第3小的,前6个第4小的)
Sample Output
3
3
1
2
大根堆分别有1、2、3、4个元素 3 ,3 1,3 1 -4 2 8 -1000,3 1 -4 2 8 -1000。。。。3,3 1,1 -4 -1000,1 -4 2 -1000。。。。_,1, -4 -1000,1 -4 -1000
小顶堆元素为 3,3,3 1 2 8,3 2 8 即负责选出最小元素
#include<iostream> #include<stdio.h> #include<queue> #include<string.h> using namespace std; const int maxint=30010; int num[maxint]; int query[maxint]; priority_queue<int ,vector <int> ,less<int> >p2;//大根堆 priority_queue<int ,vector <int> ,greater<int> >p1;//小根堆 int main() { int m,n,i,j,k; int temp; while(scanf("%d%d",&m,&n)!=EOF) { for(i=0;i<m;i++) scanf("%d",&num[i]); for(i=0;i<n;i++) scanf("%d",&query[i]); //输入结束之后,就是从头到尾维护一个大根堆和小根堆 //大根堆中始终存放在查询之前的元素 j=0; for(i=0;i<m;i++) { p2.push(num[i]);//把第i个元素放入大根堆 p1.push(p2.top());//把大根堆的最大元素放入小根堆 p2.pop(); if(query[j]==i+1)//当前询问 { while(query[j]==i+1) { temp=p1.top();//小根堆的最小元素就是第i+1小的元素,因为大根堆中的i个元素 p1.pop();//都小于temp p2.push(temp); printf("%d\n",temp); j++; } } } } return 0; }
题外话丨分治法 直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。
相关文章推荐
- 判断AL是否为十六进制并将其十进制存入AL
- LeedCode OJ -- String to Integer (atoi)
- ADO中_RecordsetPtr的使用
- 学习Linux的菜鸟(虚拟机与物理机共享文件)
- 获取手机root的方法
- 删除空格
- 无法创建Web Application项目的问题
- 90%的人不懂“创新”的真正含义,你呢?
- Linux权限管理命令
- win2008 64位 + oracle11G 64位 IIS7.5 配置WEBSERVICE
- 查找键值为key的元素
- php20140426
- js 判断多个一样的name
- 十进制转换成字符串
- 判断拓扑排序
- [树状数组][离散化]Ultra-QuickSort
- 【P000-007】分析模块——OO面向对象
- POJ A Chess Game
- VS2005调试技巧集合
- OLE操作EXCEL总结点