题目描述
有3X3 共9 个格子,其中有一个格子是空的,其他格子填满了1~8 之间不同的数字。通过移动格子可以改变数字和空格的位置,现在给你初状态和末状态,请你给出最少的移动步数。
输入
输入文件名为eight.in。
给出6 行,每行有3 个数,每两个数用一个空格空开,每个数在0~8 之间,其中0 表示空格。
前3 行表示初始状态,后3 行表示目标状态。
输出
输出文件名为eight.out。
输出一行一个数,表示从初始状态移动到目标状态的最少步数。
如果无解则输出-1。
样例输入
1 2 3
4 5 6
7 8 0
1 2 3
4 6 8
7 5 0
样例输出
4
思路:哈希判重+宽搜
代码:
var
hx:array[0..1000000]of longint;
st:array[0..200001]of string;
a:array[0..200001]of longint;
mb:string;
i,j,k,x,y,z,s,ls,m:longint;
procedure c(x:longint);
var
ch:char;
b:boolean;
begin
inc(j);
st[j]:=st[i];
ch:=st[j][k];
st[j][k]:=st[j][x];
st[j][x]:=ch;
a[j]:=a[i]+1;
if st[j]=mb then
begin
writeln(a[j]);
halt;
end;
if length(st[j])=8 then st[j]:='0'+st[j];
val(st[j],ls);
b:=true;
z:=ls mod m;
while hx[z]<>0 do
begin
if hx[z]=ls then
begin
b:=false;
break;
end;
inc(z);
end;
if b then hx[z]:=ls
else dec(j);
end;
begin
assign(input,'eight.in');
reset(input);
assign(output,'eight.out');
rewrite(output);
for i:=1 to 9 do
begin
read(ls);
x:=x*10+ls;
end;
m:=1000007; //越大越好
str(x,st[1]);
if length(st[1])=8 then st[1]:='0'+st[1];
x:=0;
for i:=1 to 9 do
begin
read(ls);
x:=x*10+ls;
end;
str(x,mb);
if length(mb)=8 then mb:='0'+mb;
i:=0;
j:=1;
while i<j do
begin
inc(i);
for k:=1 to length(st[i]) do
if st[i][k]='0' then break;
case k of
1:
begin
c(2);
c(4);
end;
2:
begin
c(1);
c(3);
c(5);
end;
3:
begin
c(2);
c(6);
end;
4:
begin
c(1);
c(5);
c(7);
end;
5:
begin
c(2);
c(4);
c(6);
c(8);
end;
6:
begin
c(3);
c(5);
c(9);
end;
7:
begin
c(4);
c(8);
end;
8:
begin
c(5);
c(7);
c(9);
end;
9:
begin
c(6);
c(8);
end;
end;
end;
writeln(-1);
end.