Cod sursa(job #1074259)

Utilizator PsychoAlexAlexandru Buicescu PsychoAlex Data 7 ianuarie 2014 13:42:28
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.11 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <stack>

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

struct huff
{
    int sum = 0;
    int val = 0;
    huff *st, *dr;
};

int n, vec[1000001];
std::queue<huff*> coadaValori1;
std::queue<huff*> coadaValori2;

huff *top = new huff;

long long sum = 0;

void addHuff()
{
    huff *p = new huff;

    ///daca coada1 e goala, atunci iau pe primele 2 din coada2 (toate sunt in ordine crescatoare)
    if(coadaValori1.empty())
    {
        p->st = coadaValori2.front();
        coadaValori2.pop();

        p->dr = coadaValori2.front();
        coadaValori2.pop();
    }
    else
        if(coadaValori2.empty())
        {
            p->st = coadaValori1.front();
            coadaValori1.pop();

            p->dr = coadaValori1.front();
            coadaValori1.pop();
        }
        else
        {
            if(coadaValori2.front()->val + coadaValori2.front()->sum < coadaValori1.front()->val + coadaValori1.front()->sum)
            {
                p->st = coadaValori2.front();
                coadaValori2.pop();
            }
            else
            {
                p->st = coadaValori1.front();
                coadaValori1.pop();
            }

            if(coadaValori2.front()->val + coadaValori2.front()->sum < coadaValori1.front()->val + coadaValori1.front()->sum)
            {
                p->dr = coadaValori2.front();
                coadaValori2.pop();
            }
            else
            {
                p->dr = coadaValori1.front();
                coadaValori1.pop();
            }
    }
    p->sum = (p->st->val + p->st->sum) + (p->dr->val + p->dr->sum);

    coadaValori2.push(p);
    top = p;
    sum += top->sum;
}

void citire()
{
    fin>>n;
    for(int i = 0; i < n; i++)
    {
        fin>>vec[i];

        huff *huffmans = new huff;
        huffmans->val = vec[i];

        coadaValori1.push(huffmans);
    }
}

std::vector<int> cript;

void dfs(huff *nod, int leng)
{
    if(nod->val != 0)
    {
        long long lg = 0;
        for(int i = 0; i < cript.size(); i++)
        {
//            std::cout<<cript[i];
            lg += ((1<<(cript.size()-i-1)) * cript[i]);
        }
//        std::cout<<": "<<leng<<' '<<lg<<' '<<nod->val<<'\n';
        std::cout<<leng<<' '<<lg<<'\n';
        fout<<leng<<' '<<lg<<'\n';
    }
    else
    {
        if(nod->st)
        {
            cript.push_back(0);
            dfs(nod->st, leng + 1);
            cript.pop_back();
        }

        if(nod->dr)
        {
            cript.push_back(1);
            dfs(nod->dr, leng + 1);
            cript.pop_back();
        }
    }
}

void rezolvare()
{
    while(coadaValori1.size() + coadaValori2.size() > 1)
    {
        addHuff();
    }
    std::cout<<sum<<'\n';
    fout<<sum<<'\n';

//    cript.push_back(0);
    dfs(top, 0);

//    for(int i = 0; i < n; i++)
//    {
//        addHuff(huffmans[i]);
//    }
}

int main()
{
    citire();
    rezolvare();
    return 0;
}