Cod sursa(job #1749772)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 28 august 2016 18:33:25
Problema Coduri Huffman Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.23 kb
#include <bits/stdc++.h>
using namespace std;

int n, x; long long ans;
vector< pair<int, int> > son(1);
vector< pair<int, long long> > sol(1);
deque < pair<long long, int> > que[2];

class reader{
private:
    static const int SIZE = 1 << 12;
    char buff[SIZE]; int ptx; FILE *in;

    void next( void ) {
        if( ++ ptx == SIZE ) {
            ptx = 0;
            fread( buff, SIZE, 1, in );
        } return;
    }

    char current( void ) {
        return buff[ptx];
    }
public:
    reader( const char *file ) {
        in = fopen( file, "r" ); ptx = 0;
        fread( buff, SIZE, 1, in );
    }

    reader &operator >>( int &val ) {
        val = 0;

        while( current() <  '0' || current() >  '9' )
            next();

        while( current() >= '0' && current() <= '9' ) {
            val = val * 10 + ( current() - '0' );
            next();
        }

        return *this;
    }
} in( "huffman.in" );
ofstream out( "huffman.out" );

pair<long long, int> move( void ) {
    pair<long long, int> ans;

    if( que[1].size() == 0 ) { ans = que[0].front(); que[0].pop_front(); } else
    if( que[0].size() == 0 ) { ans = que[1].front(); que[1].pop_front(); } else
    {
        ans = min( que[0].front(), que[1].front() );
        ( ans == que[0].front() ) ? que[0].pop_front() : que[1].pop_front();
    }

    return ans;
};

void dfs( int node, int len, long long code ) {
    if( node <= n ) {
        sol[node] = {len, code};
        return;
    }

    dfs( son[node].first , len + 1, (code << 1) + 0 );
    dfs( son[node].second, len + 1, (code << 1) + 1 );
    return;
}

int main( int argc, const char *argv[] ) {

    in >> n; sol.resize(n + 1);
    for( int i = 1; i <= n; i ++ ) {
        in >> x; son.push_back( {0, 0} );
        que[0].push_back( {x, i} );
    }

    while( que[0].size() + que[1].size() != 1 ) {
        pair<long long, int> p1 = move();
        pair<long long, int> p2 = move();

        ans += p1.first + p2.first;
        son.push_back( {p1.second, p2.second} );
        que[1].push_back( {p1.first + p2.first, ++ n} );
    }

    out << ans << "\n"; n = (n + 1) >> 1; ans = 0;
    dfs( (n << 1) - 1, 0, 0 ); sol.erase( sol.begin() );

    for( auto it : sol )
        out << it.first << " " << it.second << "\n";

    return 0;
}