Description
经过长时间的筹备工作,在Jourk,Ronny,Plipala,阿长,阿沈等人的努力下,DM实验室建立起自己的系列网站,其中包括三个大板块:DMOJ首页、DMOJ论坛、DMOJ博客。
作为一个大型的网站,数据的加工处理需要用到很多算法系统模块,通过这些模块对系统主数据库进行修改。因此,在构建DMOJ系列网站的过程中,编写了一个庞大的数据统计系统,其中包括一个寻找第k大数字的模块,对于一个数据库来说,这样一个模块的重要性不容置疑。但是,由于在修改网站的过程中,这个模块被不慎删掉了,DMOJ找到了聪明的你,希望你能帮DMOJ重写这个模块。
对于输入数据,你将按数据要求找出n个数字中的第k大数字。
关于第k大数字的解释:对于一个数字序列,计算该数字序列第k大数字,一种可行但效率不高的方法是,首先剔除数字序列中重复的数字,然后通过某种排序算法,获得剔除重复数字后的数字序列从大到小排序的数字序列,然后取从大到小排序的数字序列的第k位的数字。从另一个角度,题目中的第k大数字即是不计入数字序列中数字重复出现的部分,对于数字重复出现的情况,应该认为该数字只出现一次。
现在请聪明的你尝试设计一种可行且效率更高的方法来解决这个问题。
Input
输入数据一共有三行。
第一行有一个正整数n(n<=10000000),表示一共给出多少个数字。
第二行有一个正整数k(k<=10000000),表示要求你找出第k大数字。
第三行有n个整数,给出n个数字。对于每个整数i,均满足-10000000<=i<=10000000。
Output
输出文件共一行,包含一个整数,表示n个数字中第k大数字是多少。
Sample Input
3 2 2006 2007 2008
Sample Output
2007
#include<iostream> #include<memory> #include<queue> using namespace std; const int MAX = 20000001; bool visited[MAX]; class cmp { public: bool operator()(const int&i, const int&j){return i>j;} }; int main() { memset(visited, false, sizeof(visited)); priority_queue<int, vector<int>, cmp> q; int num, k, temp; cin>>num>>k; int currentSize=0; while(num--) { cin>>temp; if(currentSize<k && !visited[MAX/2+temp]) { currentSize++; q.push(temp); visited[MAX/2+temp]=true; } else if(currentSize>=k && !visited[MAX/2+temp] && temp>q.top()) { q.pop(); q.push(temp); visited[MAX/2+temp]=true; } } cout<<q.top()<<endl; return 0; }