肯定是搜索题无疑问,

首先要求在15步以内(包括15步)到达目标状态,也就是限定了搜索的深度,于是我们用dfs更合适

但这样复杂度仍然太大,原因就是我们在搜索中做了很多很不优的尝试

考虑当前状态若与目标状态有x处不相同,我们至少要移动x-1步才能成功

如果当前移动次数+x-1>=已找到的最小移动次数(没找到就为16),那么再往下移动肯定是没有意义的

这样我们就可以构造出估价函数,大大优化时间复杂度

bzoj1085_A*bzoj1085_搜索_02
 1 const dx:array[1..8] of integer=(-1,1,-1,1,-2,-2,2,2);
 2       dy:array[1..8] of integer=(2,2,-2,-2,-1,1,-1,1);
 3       en:array[1..5,1..5] of integer=((1,1,1,1,1),
 4                                       (0,1,1,1,1),
 5                                       (0,0,-1,1,1),
 6                                       (0,0,0,0,1),
 7                                       (0,0,0,0,0));
 8 var num,a:array[0..10,0..10] of integer;
 9     k,min,x0,y0,x1,y1,i,j,t:longint;
10     s:string;
11 
12 procedure swap(var a,b:integer);
13   var c:integer;
14   begin
15     c:=a;
16     a:=b;
17     b:=c;
18   end;
19 
20 function check:longint;
21   var i,j:integer;
22   begin
23     check:=0;
24     for i:=1 to 5 do
25       for j:=1 to 5 do
26         if a[i,j]<>en[i,j] then inc(check);
27     exit(check-1);
28   end;
29 
30 procedure dfs(x,y,d:integer);
31   var xx,yy,i,p:integer;
32   begin
33     if d>=min then exit;
34     p:=check;
35     if p=-1 then
36     begin
37       min:=d;
38       exit;
39     end;
40     if p+d>=min then exit;
41     for i:=1 to 8 do
42     begin
43       xx:=x+dx[i];
44       yy:=y+dy[i];
45       if (xx>0) and (xx<=5) and (yy>0) and (yy<=5) then
46       begin
47         swap(a[x,y],a[xx,yy]);
48         dfs(xx,yy,d+1);
49         swap(a[x,y],a[xx,yy]);
50       end;
51     end;
52   end;
53 
54 begin
55   readln(t);
56   while t>0 do
57   begin
58     min:=16;
59     k:=0;
60     for i:=1 to 5 do
61     begin
62       readln(s);
63       for j:=1 to 5 do
64       begin
65         if s[j]='*' then
66         begin
67           x0:=i;
68           y0:=j;
69           a[i,j]:=-1;
70         end
71         else a[i,j]:=ord(s[j])-48;
72       end;
73     end;
74     dfs(x0,y0,0);
75     if min=16 then writeln(-1) else writeln(min);
76     dec(t);
77   end;
78 end.
View Code