描述
给定一个数组,统计前m大的数并且把这k个数从大到小输出。
输入
第一行包含一个整数n,表示数组的大小。n < 100000。
第二行包含n个整数,表示数组的元素,整数之间以一个空格分开。每个整数的绝对值不超过100000000。
第三行包含一个整数m。m< n。
输出
从大到小输出前m大的数,每个数一行。
样例输入
10 4 5 6 9 8 7 1 2 3 0 5
样例输出
9 8 7 6 5
为了降低时间复杂度,运用快排求该问题。 1)先找到那m大的值 2)对这m大的值进行排序 如何找m大的值: 快排,找取中间值,比中间值大的在右边,小的在左边。 若右半部分正好等于m,直接返回,继续2)。 若右半部分大于m,则继续调用1),在右半部分中寻找m大的数 若右半部分小于m个,则需在左半部分需要剩下的数。 #include<iostream> #include<cstdio> #define p 100001 using namespace std; int ans=0,n,a[p],b[p],m; void swap(int &m,int &n){ int temp=m; m=n; n=temp; } void kuaipai(int s,int e,int m){//快速排序 if(s>=e) return; int k=a[s];//选定的“中间”值 int low=s,high=e; while(low!=high){ while(low<high&&a[high]>=k) high--; swap(a[low],a[high]);//若后面值比中间值小,要放在后面,可与后面的a[high]调换 while(low<high&&a[low]<=k) low++; swap(a[low],a[high]);//全部处理完后,low=high,并且“中间值”的位置为a[low] } if(e-low+1==m) return; else if(e-low+1>m) kuaipai(low+1,e,m); else kuaipai(s,low-1,m-e+low-1); } void kuai(int s,int e){ if(s>=e) return; int k=a[s]; int low=s,high=e; while(low<high){ while(low<high&&a[high]>=k) high--; swap(a[low],a[high]); while(low<high&&a[low]<=k) low++; swap(a[low],a[high]); } kuai(s,low); kuai(low+1,e); } int main() { scanf("%d",&n); for(int i=0;i<n;++i) scanf("%d",&a[i]); scanf("%d",&m); kuaipai(0,n-1,m); kuai(n-1-m,n-1); for(int i=n-1;i>n-1-m;i--){ printf("%d\n",a[i]); } }