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.
浙公网安备 33010602011771号