肯定是搜索题无疑问,
首先要求在15步以内(包括15步)到达目标状态,也就是限定了搜索的深度,于是我们用dfs更合适
但这样复杂度仍然太大,原因就是我们在搜索中做了很多很不优的尝试
考虑当前状态若与目标状态有x处不相同,我们至少要移动x-1步才能成功
如果当前移动次数+x-1>=已找到的最小移动次数(没找到就为16),那么再往下移动肯定是没有意义的
这样我们就可以构造出估价函数,大大优化时间复杂度
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.