题目来源:http://noi.openjudge.cn/ch0204/7617
7617:输出前k大的数
总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB
描述
给定一个数组,统计前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
-----------------------------------------------------
解题思路
最大堆。
建堆O(N).
make_heap(arr,arr+n);
首元素下沉,每次O(logN)
pop_heap(arr,arr+n-i);
总复杂度O(N+klogN)
如果直接用priority_queue的话是O(NlogN),会慢一些,但也能过。
-----------------------------------------------------
代码
//7617:输出前k大的数 //总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB //描述 //给定一个数组,统计前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 #include<iostream> #include<fstream> #include<algorithm> #include<queue> #include<stdio.h> using namespace std; int arr[100000] = {}; int main() { #ifndef ONLINE_JUDGE ifstream fin("0204_7617.txt"); int n,k,i; fin >> n; for (i=0; i<n; i++) { fin >> arr[i]; } fin >> k; fin.close(); make_heap(arr,arr+n); for (i=0; i<k; i++) { printf("%d\n",arr[0]); pop_heap(arr,arr+n-i); } return 0; #endif #ifdef ONLINE_JUDGE int n,k,i; scanf("%d",&n); for (i=0; i<n; i++) { scanf("%d",arr+i); } scanf("%d",&k); make_heap(arr,arr+n); for (i=0; i<k; i++) { printf("%d\n",arr[0]); pop_heap(arr,arr+n-i); } return 0; #endif }