MY*****

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.

  

posted on 2011-10-20 07:53  reflec94  阅读(256)  评论(0编辑  收藏  举报

导航