poj 1077 eight

分析:经典的八数码问题,这里用的是heap+A*。

A*很明显是用那个经典的A*,heap的维护和k短路非常像。

第二个简单A*

代码(模仿某人的):

const

  nx:array[1..9] of integer=(1,1,1,2,2,2,3,3,3);

  ny:array[1..9] of integer=(1,2,3,1,2,3,1,2,3);

  ji:array[0..9] of longint=(1,1,2,6,24,120,720,5040,40320,362880);

type

  arr=array[1..9] of integer;

var

  q:array[0..10000] of integer;

  f:array[0..10000] of arr;

  d:array[0..10000] of string;

  v:array[0..730000] of boolean;

  p,i,j,k,st,pp:longint;

  a:arr;

  ch:char;



procedure swap(var x,y:integer);

begin

  x:=x xor y;

  y:=x xor y;

  x:=x xor y;

end;



procedure swaa(var x,y:arr);

var

  k:arr;

begin

  k:=x;

  x:=y;

  y:=k;

end;



procedure swas(var x,y:string);

var

  k:string;

begin

  k:=x;

  x:=y;

  y:=k;

end;



procedure ok;

var

  k:longint;

begin

  k:=0;

  for i:=2 to 9 do

    if a[i]<>0 then

      for j:=1 to i-1 do

        if a[j]>a[i] then inc(k);

  if odd(k) then

    begin

      writeln('unsolvable');

      halt;

    end;

end;



function hash:longint;

var

  i,j,k:longint;

begin

  hash:=0;

  for i:=1 to 8 do

    if f[p,i]<>0 then

      begin

        k:=0;

        for j:=i+1 to 9 do

          if (f[p,j]<f[p,i])and(f[p,j]<>0) then inc(k);

        hash:=hash+ji[9-i]*k;

      end;

  for i:=1 to 9 do

    if f[p,i]=0 then

      hash:=hash+ji[9-i]*(9-i);

  hash:=hash+1;

end;



procedure up;

var

  fa,son:longint;

begin

  son:=p; fa:=p>>1;

  while fa>1 do

    begin

      if q[son]<q[fa] then

        begin

          swap(q[son],q[fa]);

          swas(d[son],d[fa]);

          swaa(f[son],f[fa]);

        end else exit;

      son:=fa; fa:=son>>1;

    end;

end;



procedure down;

var

  fa,son:longint;

begin

  fa:=1; son:=2;

  while son<=p do

    begin

      if (son<p)and(q[son+1]<q[son]) then inc(son);

      if q[son]<q[fa] then

        begin

          swap(q[son],q[fa]);

          swas(d[son],d[fa]);

          swaa(f[son],f[fa]);

        end else exit;

      fa:=son; son:=fa*2;

    end;

end;



procedure find(l,r:longint; ch:char);

var

  i:longint;

begin

  inc(p);

  f[p]:=f[1];

  swap(f[p,l],f[p,r]);

  i:=hash;

  if v[i] then

    begin

      dec(p);

      exit;

    end else v[i]:=true;

  d[p]:=d[1]+ch;

  q[p]:=0;

  for i:=1 to 9 do

    if f[p,i]<>0 then

      inc(q[p],abs(nx[i]-nx[f[p,i]])+abs(ny[i]-ny[f[p,i]]));

  up;

end;



begin

  for i:=1 to 3 do

    for j:=1 to 3 do

      begin

        repeat read(ch); until ch<>' ';

        inc(k);

        if ch='x' then continue;

        a[k]:=ord(ch)-48;

        inc(st,abs(i-nx[a[k]]));

        inc(st,abs(j-ny[a[k]]));

      end;

  ok;

  p:=1;

  q[1]:=st;

  f[1]:=a;

  v[hash]:=true;

  while p>0 do

    begin

      if q[1]=0 then

        begin

          writeln(d[1]);

          halt;

        end;

      for i:=1 to 9 do

        if f[1,i]=0 then

          begin

            k:=i;

            break;

          end;

      if k-3>0 then find(k,k-3,'u');

      if k+3<9 then find(k,k+3,'d');

      if (k mod 3<>1)and(k>1) then find(k,k-1,'l');

      if (k mod 3<>0)and(k<9) then find(k,k+1,'r');

      q[1]:=q[p];

      d[1]:=d[p];

      f[1]:=f[p];

      q[p]:=0;

      d[p]:='';

      dec(p);

      down;

    end;

end.

  

你可能感兴趣的:(poj)