Cod sursa(job #755570)

Utilizator XladhenianGrigorita Vlad-Stefan Xladhenian Data 6 iunie 2012 13:05:02
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.38 kb

#include <fstream>
#include <stack>
#include <queue>
#include <string.h>
using namespace std;

long N;

struct TNod;
typedef TNod *PNod;
struct TNod
{
 PNod Left,Right;
 long Index;
 long Val;
};

long long T;
long long B[1000005];
long LenB[1000005];

long QFIn,QFOut;
long QNIn,QNOut;
PNod QFrunza[1000005];
PNod QNod[1000005];

long TNodPos;
TNod Nods[2000010];

long minint(long a,long b)
{
 if (a < b)
   {
    return a;
   }
 return b;
}

void CreazaSolutie(PNod R,long CodLen,long long CodRep)
{
 if (R->Index >= 0)
   {
    LenB[R->Index] = CodLen;
    B[R->Index] = CodRep;
    T += ((long long)(R->Val)) * CodLen;
    return;
   }
 CreazaSolutie(R->Left,CodLen + 1,CodRep << 1);
 CreazaSolutie(R->Right,CodLen + 1,(CodRep << 1) | 1);
}

void AlegeNodMin(PNod &n1,PNod &n2)
{
 long QFRest = minint(2,QFIn - QFOut);
 long QNRest = minint(2,QNIn - QNOut);
 long long Vec[4];
 long i;
 for (i = 0;i < QFRest;i += 1)
  {
   Vec[i] = (QFrunza[QFOut + i]->Val << 1);
  }
 for (i = 0;i < QNRest;i += 1)
  {
   Vec[i + QFRest] = (QNod[QNOut + i]->Val << 1) | 1;
  }
 sort(Vec+0,Vec+QFRest+QNRest);
 if ((Vec[0] & 1) == 0)
   {
    n1 = QFrunza[QFOut];
    QFOut += 1;
   }
  else
   {
    n1 = QNod[QNOut];
    QNOut += 1;
   }
 if ((Vec[1] & 1) == 0)
   {
    n2 = QFrunza[QFOut];
    QFOut += 1;
   }
  else
   {
    n2 = QNod[QNOut];
    QNOut += 1;
   }
/*  
 if ((QFIn - QFOut) == 0)
   {
    n1 = QNod[QNOut];
    n2 = QNod[QNOut + 1];
    QNOut += 2;
    return;
   }
 if ((QNIn - QNOut) == 0)
   {
    n1 = QFrunza[QFOut];
    n2 = QFrunza[QFOut + 1];
    QFOut += 2;
    return;
   }
 if (QFrunza[QFOut]->Val <= QNod[QNOut]->Val)
   {
    n1 = QFrunza[QFOut];
    QFOut += 1;
    if ((QFIn - QFOut) == 0)
      {
       n2 = QNod[QNOut];
       QNOut += 1;
       return;
      }
    if (QFrunza[QFOut]->Val <= QNod[QNOut]->Val)
      {
       n2 = QFrunza[QFOut];
       QFOut += 1;
      }
     else
      {
       n2 = QNod[QNOut];
       QNOut += 1;
      }
   }
  else
   {
    n1 = QNod[QNOut];
    QNOut += 1;
    if ((QNIn - QNOut) == 0)
      {
       n2 = QFrunza[QFOut];
       QFOut += 1;
       return;
      }
    if (QFrunza[QFOut]->Val <= QNod[QNOut]->Val)
      {
       n2 = QFrunza[QFOut];
       QFOut += 1;
      }
     else
      {
       n2 = QNod[QNOut];
       QNOut += 1;
      }
   }*/
}

int main(void)
{
 long i;
 fstream fin("huffman.in",ios::in);
 fstream fout("huffman.out",ios::out);
 fin >> N;
 for (i = 0;i < N;i += 1)
  {
   Nods[i].Index = i;
  }
 for (i = 0;i < N;i += 1)
  {
   QFrunza[i] = Nods + i;
  }
 QFIn = N;
 TNodPos = N;
 for (i = 0;i < N;i += 1)
  {
   fin >> Nods[i].Val;
  }
/* for (i = 0;i < N;i += 1)
  {
   PNod n = Nods + TNodPos;
   TNodPos += 1;
   n->Left = 0;
   n->Right = 0;
   n->Index = i;
   fin >> n->Val;
   QFrunza[QFIn] = n;
   QFIn += 1;
  }*/
 while ((QFIn != QFOut) || (QNIn != (QNOut + 1)))
  {
   PNod b1,b2,bn;
   AlegeNodMin(b1,b2);
   bn = Nods + TNodPos;
   TNodPos += 1;
   bn->Left = b1;
   bn->Right = b2;
   bn->Index = -1;
   bn->Val = b1->Val + b2->Val;
   QNod[QNIn] = bn;
   QNIn += 1;
  }
 CreazaSolutie(QNod[QNOut],0,0);
 fout << T << "\n";
 for (i = 0;i < N;i += 1)
  {
   fout << LenB[i] << " " << B[i] << "\n";
  }
 fin.close();
 fout.close();
 return 0;
}