Cod sursa(job #2887669)

Utilizator Tudose_StefanTudose Alexandru Stefan Tudose_Stefan Data 9 aprilie 2022 23:06:35
Problema Coduri Huffman Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.32 kb
#include <fstream>
#include <queue>
#include <vector>
#include <iostream>

using namespace std;

ifstream fin("huffman.in");
ofstream fout("huffman.out");



struct nod{                                     ///dupa frecat indieni pe net vreo ora am descoperit
    int poz;                                   ///ca asa se genereaza arbori binari
    int valoare;
    nod * stanga;
    nod * dreapta;
};

struct rezultat{
    int nrBiti;
    long long valInB10;
};

queue <nod*> reale, virtuale;
vector <rezultat> rez;

nod * creareNod(int info = 0, int pozz = -1)
{
    nod * nou = new nod;
    nou -> poz = pozz;
    nou -> valoare = info;
    nou -> stanga = NULL;
    nou -> dreapta = NULL;
    return nou;
}

int nrSimboluri, i, simbol, k;
nod * nr1, *nr2;
long long suma;

void parcurgere(nod * tata, long long valoare, int lungbiti)
{
    lungbiti++;
    if (tata->poz == -1)
    {
        parcurgere(tata->stanga, valoare*2, lungbiti);
        parcurgere(tata->dreapta, valoare*2+1, lungbiti);
        suma += tata->valoare;
    }
    else
    {
        rez[tata->poz].nrBiti = lungbiti;
        rez[tata->poz].valInB10 = valoare;
    }
}



int main()
{
    fin >> nrSimboluri;
    rezultat rezgol;
    rezgol.nrBiti = 0;
    rezgol.valInB10 = 0;
    rez.assign(nrSimboluri, rezgol);
    for (i = 0; i < nrSimboluri; i++)
    {
        fin >> simbol;
        reale.push(creareNod(simbol, k));
        k++;
    }
    nod * prim = creareNod();
    prim -> stanga = reale.front();
    reale.pop();
    prim -> dreapta = reale.front();
    reale.pop();
    prim -> valoare = prim -> stanga -> valoare + prim -> dreapta -> valoare;
    virtuale.push(prim);
    while (reale.size() && virtuale.size())
    {
        if (reale.front()->valoare <= virtuale.front()->valoare)
        {
            nr1 = reale.front();
            reale.pop();
        }
        else
        {
            nr1 = virtuale.front();
            virtuale.pop();
        }
        if (reale.size() == 0)
        {
            nr2 = virtuale.front();
            virtuale.pop();
        }
        else if (virtuale.size() == 0)
        {
            nr2 = reale.front();
            reale.pop();
        }
        else
        {
            if (reale.front()->valoare < virtuale.front()->valoare)
            {
                nr2 = reale.front();
                reale.pop();
            }
            else
            {
                nr2 = virtuale.front();
                virtuale.pop();
            }
        }

        nod * nou = creareNod();
        nou -> stanga = nr1;
        nou -> dreapta = nr2;
        nou -> valoare = nr1 -> valoare + nr2 -> valoare;
        virtuale.push(nou);

    }
    while (virtuale.size() > 1)
    {
        nr1 = virtuale.front();
        virtuale.pop();
        nr2 = virtuale.front();
        virtuale.pop();
        nod * nou = creareNod();
        nou -> stanga = nr1;
        nou -> dreapta = nr2;
        nou -> valoare = nr1-> valoare + nr2-> valoare;
        virtuale.push(nou);
    }
    nod * radacina = virtuale.front();
    parcurgere(radacina, 0, -1);
    fout << suma << '\n';
    for (auto j : rez)
        fout << j.nrBiti << ' ' << j.valInB10 << '\n';

    //fout << radacina ->stanga ->stanga->stanga-> poz;
    return 0;
}