Cod sursa(job #2001395)

Utilizator Coroian_DavidCoroian David Coroian_David Data 16 iulie 2017 16:37:09
Problema Coduri Huffman Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.73 kb
#include <cstdio>

using namespace std;

FILE *f, *g;

struct coada
{
    int ap, i;
};

coada que[2][1000009];

int st[9];

int dr[9];

typedef long long lint;

lint cod[1000009];

int l[1000009];

int nods;

struct nodul
{
    int st, dr;
};

nodul nod[2000009];

int n;

void readFile()
{
    f = fopen("huffman.in", "r");

    fscanf(f, "%d", &n);

    int i;
    for(i = 1; i <= n; i ++)
        fscanf(f, "%d", &que[0][i].ap), que[0][i].i =i;

    fclose(f);
}

void getMn(coada &mn)
{
    int cand0;
    int cand1;

    if(st[0] <= dr[0] && st[1] <= dr[1])
    {
        if(que[0][st[0]].ap < que[1][st[1]].ap)
        {
            mn = que[0][st[0]];
            st[0] ++;
            return;
        }

        else
        {
            mn = que[1][st[1]];
            st[1] ++;
            return;
        }
    }

    if(st[0] <= dr[0])
    {
        mn = que[0][st[0]];
        st[0] ++;
        return;
    }

    ///st[1] <= dr[1];

    mn = que[1][st[1]];
    st[1] ++;
    return;
}

void DFS(int a, int secret, int len)
{


    if(nod[a].st != 0)
    {//printf("+++++++++++%d\n", a);
        DFS(nod[a].st, secret << 1, len + 1);
        DFS(nod[a].dr, (secret << 1) + 1, len + 1);

        return;
    }

  //  printf("%d\n", a);

    l[a] = len;
    cod[a] = secret;
}

lint rez;

void solve()
{
    st[0] = 1;
    dr[0] = n;

    st[1] = 1;
    dr[1] = 0;

    nods = n;
    coada mn0, mn1;
    while(st[0] + st[1] <= dr[0] + dr[1])
    {
        if(st[0] <= dr[0] && st[1] <= dr[1])
        {
            getMn(mn0);
            getMn(mn1);
        }

        else
            if(st[0] <= dr[0])
            {
                if(st[0] == dr[0])
                    break;///ERROR
                ///Cel putin 2

                mn0 = que[0][st[0]], st[0] ++;
                mn1 = que[0][st[0]], st[0] ++;
            }

        else
            if(st[1] <= dr[1])
            {
                if(st[1] == dr[1])
                    break;

                mn0 = que[1][st[1]], st[1] ++;
                mn1 = que[1][st[1]], st[1] ++;
            }

           // printf("%d %d\n", mn0, mn1);

        rez += mn0.ap + mn1.ap;

        nods ++;

        que[1][++ dr[1]].ap = mn0.ap + mn1.ap;
        que[1][dr[1]].i = nods;

        nod[nods].st = mn0.i;
        nod[nods].dr = mn1.i;
    }

    DFS(nods, 0, 0);
}

void printFile()
{
    g = fopen("huffman.out", "w");

    fprintf(g, "%lld\n", rez);

    int i;
    for(i = 1; i <= n; i ++)
        fprintf(g, "%lld %lld\n", 1LL * l[i], cod[i]);

    fclose(g);
}

int main()
{
    readFile();

    solve();

    printFile();

    return 0;
}