Cod sursa(job #2599981)

Utilizator patcasrarespatcas rares danut patcasrares Data 11 aprilie 2020 21:05:58
Problema Coduri Huffman Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.49 kb
#include<bits/stdc++.h>
using namespace std;
const int DN=1e6+5;

#define int long long

FILE *fin;
FILE *fout;

int n,m,rad;
char a[DN];
struct nod
{
    int st,dr;
    int fr;
    char ch;
    int sol;
    int h;
}r[2*DN];
map<char,int>mp,sol;
set<pair<int,int> >s;
int z;


///codeaza huffman si returneaza radacina
int solve()
{

    while(s.size()>1)
    {
        ///scot primele 2 noduri cu frecventele  mai mici
        int f=s.begin()->second;
        s.erase(s.begin());

        int g=s.begin()->second;
        s.erase(s.begin());

        m++;
        r[m].fr=r[f].fr+r[g].fr;

        r[m].ch=r[f].ch;

        r[m].st=f;
        r[m].dr=g;

        cout<<r[f].ch<<' '<<r[g].ch<<' '<<r[f].fr<<' '<<r[g].fr<<'\n';

        s.insert({r[m].fr,m});


    }
    return s.begin()->second;
}

///determina codul unui caracter descris intr-un int
void dfs(int nod)
{
    if(nod==0)
        return;
    cout<<nod<<'\n';
    r[r[nod].st].sol=r[nod].sol*2;
    r[r[nod].st].h=r[nod].h+1;
    r[r[nod].dr].h=r[nod].h+1;
    z+=r[nod].fr;
    dfs(r[nod].st);
    r[r[nod].dr].sol=r[nod].sol*2+1;
    dfs(r[nod].dr);
}

///afiseaza reprezentarea binara a unui numar
void afisare(int val)
{
    if(val==1)
        return;
    afisare(val/2);
    val%=2;
    fprintf(fout,"%d",val);
}

signed main()
{
    fin=fopen("huffman.in","r");
    fout=fopen("huffman.out","w");

    /*fscanf(fin,"%s",a);
    n=strlen(a);
    for(int i=0;i<n;i++)
        mp[a[i]]++;

    ///afisez caracterele cu frecventele lor
    fprintf(fout,"%d\n",(int)mp.size());
    for(auto i:mp)
    {
        m++;
        r[m].ch=i.first;
        r[m].fr=i.second;
        fprintf(fout,"%c %d\n",i.first,i.second);
        sol[i.first]=m;
        s.insert({i.second,m});
    }


    rad=solve();

    r[rad].sol=1;
    dfs(rad);

    ///afisez rezultatul
    for(int i=0;i<n;i++)
    {
        int pz=sol[a[i]];
        int f=r[pz].sol;
        cout<<f<<'\n';
        afisare(f);
    }*/

    fscanf(fin,"%d",&n);
    for(int i=0;i<n;i++)
    {
        int f;
        fscanf(fin,"%d",&f);
        m++;
        //r[m].ch=i.first;
        r[m].fr=f;
        //fprintf(fout,"%c %d\n",i.first,i.second);
        //sol[i.first]=m;
        s.insert({f,m});
    }

    rad=solve();

    r[rad].h=0;
    dfs(rad);
    z-=r[rad].fr;
    fprintf(fout,"%d\n",z);
    for(int i=1;i<=n;i++)
    {
        fprintf(fout,"%d %d\n",r[i].h,r[i].sol);
    }

}