Cod sursa(job #2911474)

Utilizator AndreiCroitoruAndrei Croitoru AndreiCroitoru Data 29 iunie 2022 20:47:02
Problema Coduri Huffman Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.83 kb
#include <bits/stdc++.h>

using namespace std;

/**
create a priority queue Q consisting of each unique character.
sort then in ascending order of their frequencies.
for all the unique characters:
    create a newNode
    extract minimum value from Q and assign it to leftChild of newNode
    extract minimum value from Q and assign it to rightChild of newNode
    calculate the sum of these two minimum values and assign it to the value of newNode
    insert this newNode into the tree
return rootNode
*/


int const N = 1e6 + 1;
struct node
{
    long long value;
    int st, dr, lvl;

} huffmanTree[2 * N];
long long n;
void dfs(int nod, int nivel, long long val)
{
    if(nod <= n)
    {
        huffmanTree[nod].lvl = nivel;
        huffmanTree[nod].value = val;
        return;
    }
    dfs(huffmanTree[nod].st, nivel + 1, val * 2);
    dfs(huffmanTree[nod].dr, nivel + 1, val * 2 + 1);
}


int32_t main()
{

    ifstream cin("huffman.in");
    ofstream cout("huffman.out");

    long long ans = 0;
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> huffmanTree[i].value; // sortat crescator
    }
    int inceput = 1;
    int sfarsit = n;
    int inceput2 = n + 1;
    int sfarsit2 = n;
    while(inceput <= sfarsit or inceput2 < sfarsit2)
    {
        int st, dr;
        if(inceput <= sfarsit and inceput2 <= sfarsit2)
        {
            if(huffmanTree[inceput].value <= huffmanTree[inceput2].value)
            {
                st = inceput;
                inceput ++;
            }
            else
            {
                st = inceput2;
                inceput2 ++;
            }
        }
        else if(inceput <= sfarsit)
        {
            st = inceput;
            inceput++;
        }
        else
        {
            st = inceput2;
            inceput2 ++;
        }
        if(inceput <= sfarsit and inceput2 <= sfarsit2)
        {
            if(huffmanTree[inceput].value <= huffmanTree[inceput2].value)
            {
                dr = inceput;
                inceput ++;
            }
            else
            {
                dr = inceput2;
                inceput2 ++;
            }
        }
        else if(inceput <= sfarsit)
        {
            dr = inceput;
            inceput ++;
        }
        else
        {
            dr = inceput2;
            inceput2 ++;
        }
        huffmanTree[++sfarsit2].st = st;
        huffmanTree[sfarsit2].dr = dr;
        huffmanTree[sfarsit2].value = huffmanTree[st].value + huffmanTree[dr].value;
        ans += huffmanTree[sfarsit2].value;

    }
    dfs(sfarsit2, 0, 1);
    cout << ans << '\n'; // numarul de caractere
    for(int i = 1; i <= n; i++)
    {
        cout << huffmanTree[i].lvl << " " << huffmanTree[i].value << '\n';
    }
    return 0;
}