OpenJ_Bailian 7617 输出前k大的数

题目传送门 OpenJ_Bailian 7617

描述

给定一个数组,统计前k大的数并且把这k个数从大到小输出。

输入

第一行包含一个整数n,表示数组的大小。n < 100000。
第二行包含n个整数,表示数组的元素,整数之间以一个空格分开。每个整数的绝对值不超过100000000。
第三行包含一个整数k。k < n。

输出

从大到小输出前k大的数,每个数一行。

样例输入

10
4 5 6 9 8 7 1 2 3 0
5

样例输出

9
8
7
6
5

解题思路:
  emmmmm直接sort排序然后输出就过了,偷懒了偷懒了
  排序后再输出,复杂度 O(nlogn)


  用分治处理:复杂度 O(n+mlogm)
  思路:把前m大的都弄到数组最右边,然后对这最右边m个元素排序, 再输出
  关键 :O(n)时间内实现把前m大的都弄到数组最右边
引入操作 arrangeRight(k): 把数组(或数组的一部分)前k大的都弄到最右边
  如何将前k大的都弄到最右边 :
  1)设key=a[0], 将key挪到适当位置,使得比key小的元素都在 key左边,比key大的元素都在key右边(线性时间完成)
    (直接令key=a[0]可能会TLE,所以可以考虑将key设为数组里随机的一个数)
  2) 选择数组的前部或后部再进行 arrangeRight操作
  从key到数组末尾元素个数刚好等于k时结束
  大于k时 对此a个元素再进行arrangeRigth(k)
  小于k时 对左边b个元素再进行arrangeRight(k-a)

#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 100100;
int a[N];
int main()
{
    int n,k;
    scanf("%d",&n);
    for (int i=0;i<n;i++)
        scanf("%d",&a[i]);
    scanf("%d",&k);
    sort(a,a+n);
    for (int i=n-1;k;i--,k--)
        printf("%d\n",a[i]);
    return 0;
}
排序

 



posted @ 2018-07-24 22:52  19呀  阅读(344)  评论(0编辑  收藏  举报