Cod sursa(job #2251534)

Utilizator paul_danutDandelion paul_danut Data 1 octombrie 2018 18:13:10
Problema Coduri Huffman Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.52 kb
#include <fstream>
#include <queue>
#include <cstdio>


struct Node { long long val; long leftPos, rightPos;};

Node nodes[2000001];
long long len[1000001];
long long code[1000001];

int getNodePosWithMinValue(Node nodes[], std::queue<long>& initial, std::queue<long>& internal)
{
    long pos = -1;
    if(initial.empty())
    {
        pos = internal.front();
        internal.pop();
    }
    else if(internal.empty())
    {
        pos = initial.front();
        initial.pop();
    }
    else
    {
        long initialFront = initial.front();
        long internalFront = internal.front();
        if(nodes[initialFront].val < nodes[internalFront].val)
        {
            pos = initialFront;
            initial.pop();
        }
        else
        {
            pos = internalFront;
            internal.pop();
        }
    }

    return pos;
}

long Huffman(Node nodes[], long n, std::queue<long> initial)
{
    std::queue<long> internal;

    while( ( initial.size() + internal.size() ) > 1)
    {

        long leftPos = getNodePosWithMinValue(nodes, initial, internal);
        long rightPos = getNodePosWithMinValue(nodes, initial, internal);

        nodes[++n].val = nodes[leftPos].val + nodes[rightPos].val;
        nodes[n].leftPos = leftPos;
        nodes[n].rightPos = rightPos;

        internal.push(n);
    }

    return internal.front();
}

void DepthFirst(Node nodes[], long pos, long long val = 0, long length = 0)
{
    if (nodes[pos].leftPos != -1)
    {
        DepthFirst(nodes, nodes[pos].leftPos, val * 2, length + 1);
    }

    if (nodes[pos].rightPos != -1)
    {
        DepthFirst(nodes, nodes[pos].rightPos, val * 2 + 1, length + 1);
    }

    if (nodes[pos].rightPos == -1 && nodes[pos].leftPos == -1)
    {
        len[pos] = length;
        code[pos] = val;
    }
}

int main()
{
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);

    long n;
    scanf("%ld", &n);

    std::queue<long> initial;

    for(long i = 0; i < n; ++i)
    {
        scanf("%lld", &nodes[i].val);
        nodes[i].leftPos = -1;
        nodes[i].rightPos = -1;

        initial.push(i);
    }

    long root = Huffman(nodes, n, initial);
    DepthFirst(nodes, root);

    long long lg = 0;
    for (long i = 0; i < n; ++i)
    {
        lg += len[i] * nodes[i].val;
    }

    printf("%lld\n", lg);

    for (long i = 0; i < n; ++i)
    {
        printf("%lld %lld\n", len[i], code[i]);
    }

    return 0;
}