先说点题外话,昨天看了cq学长写的日志,他说我们的语言表达能力太弱,我觉得很对,以前写解题报告的时候,虽然知道怎么做出来的,可是就是无法用语言清晰的表达出来,有时嫌麻烦就直接粘了别人的一些话了说明,一篇报告总是弄的前言不搭后语的,其实语言表达能力也很重要。所以,以后会让自己尽量少的引用别人的话,尽量用自己的语言表达出想表达的意思。
现在再来说说这道题,其实是一道很水的题,不过题意很容易让人误解,我就被误解了~~这题是用到了堆,不过如果我告诉你这题其实就是让你求第K小数的话,相信你不用优先队列也一样可以求出来。
解题思路:用分治法,是大顶堆的堆顶元素始终小于小顶堆的堆顶元素,这样的话大顶堆中的所有元素都小于小顶堆中的元素,如果大顶堆中有k-1个元素,那么小顶堆的堆顶元素就是要找的第k小元素了~
代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> #define maxx 30005 #define INF 0xffffff using namespace std ; struct cmp1 { bool operator()( const int a , const int b ) { return a > b; } }; struct cmp2 { bool operator () ( const int a , const int b ) { return a < b ; } }; int a[maxx] ; int main() { int n , m , i , j ; priority_queue<int , vector<int> , cmp1>q1 ;//小顶堆 priority_queue<int , vector<int> , cmp2>q2 ;//大顶堆 while ( scanf ( "%d%d" , &n , &m ) != EOF ) { for ( i = 0 ; i < n ; i++ ) scanf ( "%d" , &a[i] ); j = 0 ; for ( i = 0 ; i < m ; i++ ) { int p ; scanf ( "%d" , &p); while ( j < p ) { q1.push ( a[j] ); if ( !q2.empty( ) && q1.top( ) < q2.top( ) )//交换元素 { int t1 = q1.top( ) ; q1.pop() ; int t2 = q2.top( ) ; q2.pop() ; q1.push( t2 ); q2.push( t1 ); } j++ ; } printf ( "%d\n" , q1.top( ) ); q2.push( q1.top( )); q1.pop(); } } return 0; }