SDUT-3401 数据结构实验之排序四:寻找大富翁(堆排序)
2017-12-23 11:38
344 查看
数据结构实验之排序四:寻找大富翁
Time Limit: 200MS Memory Limit: 512KBSubmit Statistic
Problem Description
2015胡润全球财富榜调查显示,个人资产在1000万以上的高净值人群达到200万人,假设给出N个人的个人资产值,请你快速找出排前M位的大富翁。
Input
首先输入两个正整数N( N ≤ 10^6)和M(M ≤ 10),其中N为总人数,M为需要找出的大富翁数目,接下来给出N个人的个人资产,以万元为单位,个人资产数字为正整数,数字间以空格分隔。
Output
一行数据,按降序输出资产排前M位的大富翁的个人资产值,数字间以空格分隔,行末不得有多余空格。
Example Input
6 3 12 6 56 23 188 60
Example Output
188 60 56
Hint
请用堆排序完成。
Author
xam参考:https://www.cnblogs.com/mengdd/archive/2012/11/30/2796845.html
参考:http://blog.csdn.net/xiaoxiaoxuewen/article/details/7570621/
此题因为数组较大,使用高效排序依然可能超时,但因为M较小,所以由此入手,输入前M个数后,每次循坏找M个中最小的和新输入的
进行比较,若小于新输入的,则替换。
#include <bits/stdc++.h>///数组下标从0开始 using namespace std; int a[12]; void adjust(int s,int e)///调整堆 { int temp=a[s]; for(int i=s*2+1;i<=e;i*=2)/*为什么等于e:e不一定等于m,而且下面if有判断i<e,所以不用担心数组越界;i*=2:因为调整过后可能孩子堆被破坏,所以数组下标跳到孩子继续调整*/ { if(i<e&&a[i]<a[i+1])///找到两个孩子中较大的 i++; if(temp>a[i])///若大于两个孩子,则无需进行后面的判断,退出循环 break; a[s]=a[i]; s=i;///完成一次调整后,堆顶变为i } a[s]=temp;///中途循坏退出,则再把调整前的堆顶记录插入到现在的堆顶 } void Heap(int n) { for(int i=(n/2)-1; i>=0; i--)///依照从下到上的顺序构建堆,因为n/2之后的是叶子结点,所以无需调整 { adjust(i,n); } for(int i=n-1; i>=1; i--)///共n个结点,所以调整n-1次 { swap(a[0],a[i]); adjust(0,i-1); } } int main() { std::ios::sync_with_stdio(false);///防止超时 int n,m,x,k=0,l; cin>>n>>m; for(int i=1; i<=n; i++) { cin>>x; if(k<m) a[k++]=x; else { l=0; for(int j=1; j<m; j++) { if(a[l]>a[j])///记录m个数中的最小值 l=j; } if(a[l]<x)///若最小的小于x,就把他替换掉 a[l]=x; } } Heap(m);///只对前m个构建堆 for(int i=m-1; i>=0; i--) { if(i==m-1) cout<<a[i]; else cout<<' '<<a[i]; } cout<<endl; return 0; }
#include <bits/stdc++.h>///数组下标从1开始 using namespace std; int a[100]; void adjust(int i,int n)///调整堆 { int left=i*2;///左子树结点 int right=i*2+1;///右子树结点 int ma=i; if(i<=n/2)///n/2之后的是叶子结点,无需调整 { if(left<=n&&a[left]>a[ma])///找到三个点中的最大的 { ma=left; } if(right<=n&&a[right]>a[ma]) { ma=right; } if(ma!=i)///若左右子树的值大于根,就交换两者的值 { swap(a[i],a[ma]); adjust(ma,n);///若交换了值,则需要调整他们的孩子使孩子也是堆 } } } void Heap(int n) { for(int i=(n/2); i>=1; i--)///依照从下到上的顺序构建堆,因为n/2之后的是叶子结点,所以无需调整 { adjust(i,n); } for(int i=n; i>=2; i--)///共n个结点,所以调整n-1次 { swap(a[1],a[i]); adjust(1,i-1); } } int main() { std::ios::sync_with_stdio(false);///防止超时 int n,m,x,k=1,l; cin>>n>>m; for(int i=1; i<=n; i++) { cin>>x; if(k<m+1) a[k++]=x; else { l=1; for(int j=2; j<k; j++) { if(a[l]>a[j])///记录m个数中的最小值 l=j; } if(a[l]<x)///若最小的小于x,就把他替换掉 a[l]=x; } } Heap(m);///只对前m个构建堆 for(int i=m; i>=1; i--) { if(i==m) cout<<a[i]; else cout<<' '<<a[i]; } cout<<endl; return 0; }
相关文章推荐
- SDUT 3401 数据结构实验之排序四:寻找大富翁(堆排序)
- SDUT 3401 数据结构实验之排序四:寻找大富翁 堆排序
- SDUT 3401 数据结构实验之排序四:寻找大富翁
- 数据结构实验之排序四:寻找大富翁(堆排序)
- SDUT OJ 3401 数据结构实验之排序四:寻找大富翁
- SDUTOJ(3401)数据结构实验之排序四:寻找大富翁
- 数据结构实验之排序四:寻找大富翁(堆排序)
- 3401 数据结构实验之排序四:寻找大富翁
- 数据结构实验之排序四:寻找大富翁——堆排序
- 数据结构实验之排序四:寻找大富翁(堆排序)
- 数据结构实验之排序四:寻找大富翁 sdut oj (3401)
- 数据结构实验之排序四:寻找大富翁---3401
- 数据结构实验之排序四:寻找大富翁(堆排序)
- 数据结构实验之排序四:寻找大富翁
- 数据结构实验之排序四:寻找大富翁
- 数据结构实验之排序四:寻找大富翁
- 数据结构实验之排序四:寻找大富翁
- 数据结构实验之排序四:寻找大富翁
- 数据结构之排序之堆排序。寻找大富翁
- 数据结构实验之排序四:寻找大富翁