Cod sursa(job #964663)

Utilizator RusuAlexeiRusu Alexei RusuAlexei Data 21 iunie 2013 22:31:12
Problema Coduri Huffman Scor 80
Compilator fpc Status done
Runda Arhiva educationala Marime 2.87 kb
program huffman;

  type nod=record
             info:int64;
             y,lefty,righty:byte;
             x,
             leftx,
             rightx:longint;
           end;

  var  bufin,bufout:array [1..100000] of byte;
       a:array [0..1,1..1000000] of nod;
       height,binar:array [1..1000000] of longint;
       n,i,j,h:longint;
       lung:int64;


procedure dfs(u:nod;h,bin:int64);
  begin
    if u.y=0 then
      begin
        height[u.x]:=h;
        binar[u.x]:=bin;
      end else
      begin
        dfs(a[u.lefty,u.leftx],h+1,2*bin);
        dfs(a[u.righty,u.rightx],h+1,2*bin+1);
      end
  end;

begin
  assign(input,'huffman.in');
  reset(input);
  settextbuf(input,bufin);
  assign(output,'huffman.out');
  rewrite(output);
  settextbuf(output,bufout);

  readln(n);
  for i:=1 to n do
    begin
      readln(a[0,i].info);
      a[0,i].x:=i;
      a[0,i].y:=0;
    end;


  j:=1; h:=1;
  for i:=1 to n-1 do
    begin
      a[1,i].x:=i;
      a[1,i].y:=1;

      if h<i then
        begin
          if j>n then
            begin
              a[1,i].info:=a[1,h].info;
              a[1,i].leftx:=a[1,h].x;
              a[1,i].lefty:=a[1,h].y;
              inc(h);
            end else begin
          if a[1,h].info<a[0,j].info then
            begin
              a[1,i].info:=a[1,h].info;
              a[1,i].leftx:=a[1,h].x;
              a[1,i].lefty:=a[1,h].y;
              inc(h);
            end else
            begin
              a[1,i].info:=a[0,j].info;
              a[1,i].leftx:=a[0,j].x;
              a[1,i].lefty:=a[0,j].y;
              inc(j);
            end;
        end;end else
        begin
            a[1,i].info:=a[0,j].info;
              a[1,i].leftx:=a[0,j].x;
              a[1,i].lefty:=a[0,j].y;
              inc(j);
        end;


      if h<i then
        begin
          if j>n then
            begin
              a[1,i].info:=a[1,i].info+a[1,h].info;
              a[1,i].rightx:=a[1,h].x;
              a[1,i].righty:=a[1,h].y;
              inc(h);
            end else begin
          if a[1,h].info<a[0,j].info then
            begin
               a[1,i].info:=a[1,i].info+a[1,h].info;
              a[1,i].rightx:=a[1,h].x;
              a[1,i].righty:=a[1,h].y;
              inc(h);
            end else
            begin
              a[1,i].info:=a[1,i].info+a[0,j].info;
              a[1,i].rightx:=a[0,j].x;
              a[1,i].righty:=a[0,j].y;
              inc(j);
            end;
        end;end else
        begin
          a[1,i].info:=a[1,i].info+a[0,j].info;
              a[1,i].rightx:=a[0,j].x;
              a[1,i].righty:=a[0,j].y;
              inc(j);
        end;

      lung:=lung+a[1,i].info;
    end;

  writeln(lung);
  dfs(a[1,n-1],0,0);
  for i:=1 to n do writeln(height[i],' ',binar[i]);
  close(output);
end.