Cod sursa(job #979986)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 3 august 2013 17:19:46
Problema Sortare prin comparare Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.78 kb
#include <iostream>
#include <fstream>

using namespace std;

typedef int MinMaxHeap[500005];

const unsigned int inf = ( 1 << 31 );

MinMaxHeap H;
int N;

int log2( int key )
{
    int val = -1;

    while( key )
    {
        val++;
        key >>= 1;
    }

    return val;
}

void UpHeapMax( int index );
void UpHeapMin( int index );

void UpHeapMax( int index )
{
    int ind = index;

    while( index/4 >= 1 && H[index/4] < H[index] )
    {
        swap( H[index/4], H[index] );
        index = index/4;
    }

    if ( ind <= 1 )
            return;

    if ( H[ind/2] > H[ind] )
    {
        swap( H[ind/2], H[ind] );
        UpHeapMin( ind/2 );
    }
}

void UpHeapMin( int index )
{
    int ind = index;

    while( index/4 >= 1 && H[index/4] > H[index] )
    {
        swap( H[index/4], H[index] );
        index = index/4;
    }

    if ( ind <= 1 )
            return;

    if ( H[ind/2] < H[ind] )
    {
        swap( H[ind/2], H[ind] );
        UpHeapMax( ind/2 );
    }
}

int min2generations( int ind )
{
    unsigned int minim = inf;
    int pozitie = -1;

    for ( int i = 0; i < 2; i++ )
    {
        if ( 2*ind+i <= N && H[2*ind+i] < minim )
        {
            minim = H[2*ind+i];
            pozitie = 2*ind+i;
        }
    }

    for ( int i = 0; i < 4; i++ )
    {
        if ( 4*ind+i <= N && H[4*ind+i] < minim )
        {
            minim = H[4*ind+i];
            pozitie = 4*ind+i;
        }
    }

    return pozitie;
}

int max2generations( int ind )
{
    long long minim = 0;
    int pozitie = -1;

    for ( int i = 0; i < 2; i++ )
    {
        if ( 2*ind+i <= N && H[2*ind+i] > minim )
        {
            minim = H[2*ind+i];
            pozitie = 2*ind+i;
        }
    }

    for ( int i = 0; i < 4; i++ )
    {
        if ( 4*ind+i <= N && H[4*ind+i] > minim )
        {
            minim = H[4*ind+i];
            pozitie = 4*ind+i;
        }
    }

    return pozitie;
}

void push( int key )
{
    H[ ++N ] = key;

    int niv = log2( N );

    if ( niv % 2 == 0 )
            UpHeapMin( N );
    else
            UpHeapMax( N );
}

void pop_min()
{
    int i, last, m, parent;

    int x = H[ N-- ];

    for ( i = 1, last = N/2; i <= last; )
    {
        m = min2generations( i );

        if ( m == -1 )
            break;

        if ( x <= H[m] )
                break;

        H[i] = H[m];

        if ( m <= 2*i+1 )
        {
            i = m;
            break;
        }

        parent = m/2;

        if ( x > H[parent] )
                swap( H[parent], x );

        i = m;
    }

    H[i] = x;
}

int top_max()
{
    if ( N == 1 )
            return H[1];

    if ( N == 2 )
        return max( H[1], H[2] );

    return max( H[2], H[3] );
}

void pop_max()
{
    int poz = 2;

    if ( H[3] > H[2] )
            poz = 3;

    int i, last, m, parent;

    int x = H[ N-- ];

    for ( i = poz, last = N/2; i <= last; )
    {
        m = max2generations( i );

        if ( m == -1 )
            break;

        if ( x >= H[m] )
                break;

        H[i] = H[m];

        if ( m <= 2*i+1 )
        {
            i = m;
            break;
        }

        parent = m/2;

        if ( x < H[parent] )
                swap( H[parent], x );

        i = m;
    }

    H[i] = x;
}

int main()
{
    int n = 0;

    ifstream f("algsort.in");
    ofstream g("algsort.out");

    f >> n;

    for ( int i = 1, a; i <= n; i++ )
    {
        f >> a;
        push(a);
    }

    int a[500500];

    for ( int i = n; i >= 1; i-- )
    {
         a[i] = top_max();
         pop_max();
    }

    for ( int i = 1; i <= n; i++ )
            g << a[i] << " ";
}