Cod sursa(job #2022296)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 16 septembrie 2017 11:42:08
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.25 kb
#include <bits/stdc++.h>

FILE *fi, *fout;

const int MAXBUF = (int) (1 << 17);

char buf[MAXBUF];
int pbuf = MAXBUF;

inline char nextch() {
    if(pbuf == MAXBUF) {
        fread(buf, 1, MAXBUF, fi);
        pbuf = 0;
    }
    return buf[pbuf++];
}

inline int getnr() {
    char ch = nextch();
    while(!isdigit(ch))
        ch = nextch();
    int nr = 0;
    while(isdigit(ch)) {
        nr = nr * 10 + ch - '0';
        ch = nextch();
    }
    return nr;
}

const int MAXN = (int) 1e6;
const long long INF = (1LL << 62);

long long v[2 * MAXN + 1];

int q1[MAXN + 1], q2[MAXN + 1];

std::vector <int> g[MAXN + 1];

char bit[MAXN + 1];

int n;

void dfs(int nod, long long conf, char lvl) {
    if(nod <= n) {
        v[nod] = conf;
        bit[nod] = lvl;
    }
    for(int i = 0; i < g[nod].size(); i++)
        dfs(g[nod][i], conf * 2 + i, lvl + 1);
}

int main() {
    int i;
    fi = fopen("huffman.in" ,"r");
    fout = fopen("huffman.out" ,"w");
    n = getnr();
    for(i = 1; i <= n; i++) {
        v[i] = getnr();
        q1[i - 1] = i;
    }
    long long ans = 0;
    int b1 = 0, e1 = n;
    int b2 = 0, e2 = 0;
    for(i = 1; i < n; i++) {
        long long val1 = INF, val2 = INF, val3 = INF;
        if(b1 + 1 < e1)
            val1 = v[q1[b1]] + v[q1[b1 + 1]];
        if(b1 < e1 && b2 < e2)
            val2 = v[q1[b1]] + v[q2[b2]];
        if(b2 + 1 < e2)
            val3 = v[q2[b2]] + v[q2[b2 + 1]];
        long long min = std::min(val1, std::min(val2, val3));
        if(val1 == min) {
            g[i + n].push_back(q1[b1]);
            g[i + n].push_back(q1[b1 + 1]);
            b1 += 2;
        }
        else if(val2 == min) {
            g[i + n].push_back(q1[b1]);
            g[i + n].push_back(q2[b2]);
            b1++;
            b2++;
        }
        else if(val3 == min) {
            g[i + n].push_back(q2[b2]);
            g[i + n].push_back(q2[b2 + 1]);
            b2 += 2;
        }
        ans += min;
        q2[e2] = n + i;
        v[n + i] = min;
        e2++;
    }
    dfs(2 * n - 1, 0, 0);
    fprintf(fout,"%lld\n" ,ans);
    for(i = 1; i <= n; i++)
        fprintf(fout,"%d %lld\n" ,bit[i],v[i]);
    fclose(fi);
    fclose(fout);
    return 0;
}