Cod sursa(job #386066)

Utilizator M@2Te4iMatei Misarca M@2Te4i Data 23 ianuarie 2010 22:57:10
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
#include <fstream>
#include <iostream>
#include <cstring>

#define v 1000005

using namespace std;

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

struct nod
{
    long long val;
    nod *st, *dr;
};

nod *a[v], *q[v];
long long x[v], lg=0;
int n, c[v], f[v];

void citire()
{
    fin >> n;
    memset(a,0,sizeof(a));
    int x;
    for (int i=0; i<n; i++)
    {
        fin >> x;
        a[i]=new nod;
        a[i]->val=x;
        a[i]->st=a[i]->dr=0;
    }
}

long long huffman()
{
    memset(q,0,sizeof(q));
    int w,d,s;
    nod *m1, *m2;
    for (d=w=0, s=-1; w<n ||  d<s;)
    {
        m1=a[w], m2=a[w+1];
        w+=2;
        if (q[d] && (!m1 || q[d]->val<m1->val))
        {
            m2=m1;
            m1=q[d];
            w--, ++d;
            if (q[d] && (!m2 || q[d]->val<m2->val))
            {
                m2=q[d];
                --w, ++d;
            }
        }
        else if (q[d] && (!m2 || q[d]->val<m2->val))
        {
            m2=q[d];
            --w, ++d;
        }
        q[++s]=new nod;
        q[s]->val=m1->val+m2->val;
        q[s]->st=m1;
        q[s]->dr=m2;
    }
    return s;
}

void coduri(nod *s, int niv)
{
    long long j=1L;
    if (s->st==0 && s->dr==0)
    {
        f[++f[0]]=niv;
        x[f[0]]=0;
        for (int i=niv; i>0; i--)
            x[f[0]]+=c[i]*j, j*=(long long)2;
    }
    else
    {
        lg+=s->val;
        c[niv+1]=0;
        coduri(s->st,niv+1);
        c[niv+1]=1;
        coduri(s->dr,niv+1);
    }
}

void sortare(int l, int r)
{
    int i, j, aux=0, mij;
    long long auxl=0L;
    i=l, j=r;
    mij=f[(l+r)/2];
    do
    {
        while (f[i]<mij)
            ++i;
        while (f[j]>mij)
            --j;
        if (i<=j)
        {
            aux=f[i];
            f[i]=f[j];
            f[j]=aux;
            auxl=x[i];
            x[i]=x[j];
            x[j]=auxl;
            ++i;
            --j;
        }
    }
    while (i<=j);
    if (l<j) sortare (l,j);
    if (i<r) sortare (i,r);
}

int main()
{
    citire();
    long long b=huffman();
    coduri(q[b],0);
    fout << lg << "\n";
    sortare(1, f[0]);
    for (int i=f[0]; i; i--)
        fout << f[i] << " " << (long long)x[i] << "\n";
    return 0;
}