Cod sursa(job #381343)

Utilizator PopaStefanPopa Stefan PopaStefan Data 10 ianuarie 2010 13:50:20
Problema Coduri Huffman Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.81 kb
#include<fstream>
#include<string.h>
#include<math.h>
#define infinit 10000000
#define nmax 1000000

using namespace std;

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

int n,m;
char a[1000];
long long lg=0;

struct nod
  {long long frecv;
   int folosit;
   long cod,lungime; //in baza 10
   nod *st,*dr;
  };
nod *prim[nmax];

void creare()
{int i,k;
long long frecventa;
long long min1,min2;
int pmin1,pmin2;
fin>>n;
m=n;
for(i=1;i<=n;i++)
  {fin>>frecventa;
   prim[i]=new nod;
   prim[i]->frecv=frecventa;
   prim[i]->folosit=0;
   prim[i]->st=prim[i]->dr=NULL;
  }
for(k=n-1;k>=1;k--)
  {min1=min2=infinit;
   for(i=1;i<=n;i++)
    if(prim[i]->folosit==0)
      {if(prim[i]->frecv<min1)
         {min2=min1;
          pmin2=pmin1;
         min1=prim[i]->frecv;
          pmin1=i;
         }
       else
         if(prim[i]->frecv<min2)
           {min2=prim[i]->frecv;
            pmin2=i;
           }
      }
  n++;
  prim[n]=new nod;
  prim[n]->frecv=prim[pmin1]->frecv+prim[pmin2]->frecv;
  prim[n]->folosit=0;
  prim[pmin1]->folosit=1;
  prim[pmin2]->folosit=1;
  prim[n]->st=prim[pmin1];
  prim[n]->dr=prim[pmin2];
  }
}

long long transformare(char a[1000])
{long long x=0;
int l,v;
for(l=strlen(a)-1,v=0;l>=0;l--,v++)
  if(a[l]=='1')
    x=x+pow(2,v);
return x;
}

void dfs(nod *tata,int poz)
{if(tata->st!=NULL)
  {a[poz]='0';
   dfs(tata->st,poz+1);
   a[poz]='1';
   dfs(tata->dr,poz+1);
  }
 else {a[poz]='\0';
       tata->lungime=poz;
       lg=lg+poz*tata->frecv;
       tata->cod=transformare(a);
      }
}

int main()
{creare(); //arbore Huffman
dfs(prim[n],0); //parcurgere si creeare coduri
fout<<lg<<'\n';
for(int i=1;i<=m;i++)
  fout<<prim[i]->lungime<<" "<<prim[i]->cod<<'\n';
fin.close();
fout.close();
return 0;
}