Cod sursa(job #964661)

Utilizator RusuAlexeiRusu Alexei RusuAlexei Data 21 iunie 2013 22:16:30
Problema Coduri Huffman Scor 70
Compilator fpc Status done
Runda Arhiva educationala Marime 3.22 kb
program huffman;

  type nod=record
             info:int64;
             x,y,
             leftx,lefty,
             rightx,righty:longint;
           end;
       lista=^celula;
       celula=record
                nodd:nod;
                next:lista;
              end;
  var  bufin,bufout:array [1..100000] of byte;
       a:array [0..1,1..1000000] of nod;
       height,binar:array [1..1000000] of int64;
       n,i,j:longint;
       l,v,r:lista;
       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;
  for i:=1 to n-1 do
    begin
      a[1,i].x:=i;
      a[1,i].y:=1;

      if l<>nil then
        begin
          if j>n then
            begin
              a[1,i].info:=l^.nodd.info;
              a[1,i].leftx:=l^.nodd.x;
              a[1,i].lefty:=l^.nodd.y;
              l:=l^.next;
            end else begin
          if l^.nodd.info<a[0,j].info then
            begin
              a[1,i].info:=l^.nodd.info;
              a[1,i].leftx:=l^.nodd.x;
              a[1,i].lefty:=l^.nodd.y;
              l:=l^.next;
            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 l<>nil then
        begin
          if j>n then
            begin
              a[1,i].info:=a[1,i].info+l^.nodd.info;
              a[1,i].rightx:=l^.nodd.x;
              a[1,i].righty:=l^.nodd.y;
              l:=l^.next;
            end else begin
          if l^.nodd.info<a[0,j].info then
            begin
               a[1,i].info:=a[1,i].info+l^.nodd.info;
              a[1,i].rightx:=l^.nodd.x;
              a[1,i].righty:=l^.nodd.y;
              l:=l^.next;
            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;
      new(r);
      r^.nodd:=a[1,i];
      r^.next:=nil;
      if l=nil then
        begin
          l:=r;
          v:=r;
        end else
        begin
          v^.next:=r;
          v:=r;
        end;
    end;

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