NOI 2.4 分治 7617:输出前k大的数

题目来源:http://noi.openjudge.cn/ch0204/7617

7617:输出前k大的数

总时间限制: 10000ms   单个测试点时间限制: 1000ms  内存限制: 65536kB

描述

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

输入

第一行包含一个整数n,表示数组的大小。n < 100000
第二行包含n个整数,表示数组的元素,整数之间以一个空格分开。每个整数的绝对值不超过100000000
第三行包含一个整数kk < 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
}


猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/80420042