poj 1442 Black Box

先说点题外话,昨天看了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;
}
原文地址:https://www.cnblogs.com/misty1/p/2522513.html