Cod sursa(job #144465)

Utilizator Pepelea_FlaviuFlaviu Pepelea Pepelea_Flaviu Data 27 februarie 2008 18:09:25
Problema Barbar Scor 100
Compilator fpc Status done
Runda Arhiva de probleme Marime 3.9 kb
{BARBAR  -  100 pct     ATENTIE LA BORDURI :))}  
type coord=record  
      x,y:word;  
    end;  
type pelem=^elem;  
     elem=record  
       info:coord;  
       next:pelem;  
     end;  
const dx:array[1..4]of integer=(0,0,1,-1);  
      dy:array[1..4]of integer=(1,-1,0,0);  
const nmax=65000;  
var fi,fo:text;  
    R,C,i,j,iu,ju,xi,yi,xf,yf,k,max:longint;  
    first,last:pelem;  
    a:array[0..1011,0..1011]of char;  
    o,oo:array[0..1011,0..1011]of word;  
    pc,pu:coord;  
procedure qout(var vl:coord);  
var p:pelem;  
begin  
  p:=first;  
  vl:=first^.info;  
  first:=first^.next;  
  dispose(p);  
end;  
procedure qin(vl:coord);  
var p:pelem;  
begin  
  new(p);  
  p^.info:=vl;  
  p^.next:=nil;  
  if first=nil then  
    begin  
      first:=p;  
      last:=first;  
    end  
  else  
    begin  
      last^.next:=p;  
      last:=p;  
    end;  
end;  
function verif(m,ct:longint):boolean;  
var i,j,k:word;  
begin  
  if o[xi,yi]<m then  
     begin  
       verif:=false;  
       exit;  
     end;  
  pc.x:=xi;                               {verificarea distantei maxime}  
  pc.y:=yi;                               {fata de cel mai apropiat dragon}  
  qin(pc);  
  oo[xi,yi]:=ct;  
  while first<>nil do  
    begin  
      qout(pc);  
      i:=pc.x;  
      j:=pc.y;  
      for k:=1 to 4 do  
        begin  
          iu:=i+dx[k]; ju:=j+dy[k];  
          if (oo[iu,ju]<ct)and(o[iu,ju]>=m)and(a[iu,ju]='.') then  
            begin  
              oo[iu,ju]:=ct;  
              pu.x:=iu; pu.y:=ju; qin(pu);  
            end;  
        end;  
    end;  
  if oo[xf,yf]<>ct then verif:=false  
                   else verif:=true;  
end;  
function binary_search(st,dr:longint):longint;  
var mij,rez,ct:longint;  
begin  
  rez:=-1; ct:=0;  
  while st<=dr do                         {cautarea binara}  
    begin                                 {a distantei maxime}  
      mij:=(st+dr) shr 1;                 {fata de cel mai apropiat dragon}  
      inc(ct);  
      if verif(mij,ct) then  
        begin  
          rez:=mij;  
          st:=mij+1;  
        end  
      else  
        dr:=mij-1;  
    end;  
  binary_search:=rez;  
end;  
begin  
  assign(fi,'barbar.in'); reset(fi);  
  assign(fo,'barbar.out'); rewrite(fo);  
  readln(fi,R,C);  
  for i:=1 to R do  
    begin  
      for j:=1 to C do  
        begin  
          read(fi,a[i,j]);  
          o[i,j]:=nmax;  
          if a[i,j]='I' then  
            begin  
              xi:=i;  
              yi:=j;  
              a[i,j]:='.';  
            end;  
          if a[i,j]='O' then              {citire date}  
            begin                         {si construire matrice}  
              xf:=i;  
              yf:=j;  
              a[i,j]:='.';  
            end;  
          if a[i,j]='D' then  
            begin  
              o[i,j]:=0;  
              pc.x:=i; pc.y:=j;  
              qin(pc);  
            end;  
        end;  
      readln(fi);  
    end;  
  for i:=0 to R+1 do  
    begin  
      a[i,0]:='*';  
      a[i,C+1]:='*';  
    end;                                  {bordare matrice}  
  for i:=0 to C+1 do  
    begin  
      a[0,i]:='*';  
      a[0,R+1]:='*';  
    end;  
  max:=0;  
  while first<>nil do  
    begin  
      qout(pc);  
      i:=pc.x;                            {aflare distanta minima}  
      j:=pc.y;                            {fata de cel mai apropiat dragon}  
      for k:=1 to 4 do  
        begin  
          iu:=i+dx[k]; ju:=j+dy[k];  
          if (a[iu,ju]='.')and(o[iu,ju]>o[i,j]+1) then  
            begin  
              o[iu,ju]:=o[i,j]+1;  
              if o[iu,ju]>max then max:=o[iu,ju];  
              pu.x:=iu; pu.y:=ju; qin(pu);  
            end;  
        end;  
    end;  
  writeln(fo,binary_search(0,max));  
  close(fi);  
  close(fo);  
end.