骑士精神(BZOJ1085) 题解

【问题描述】

    在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。

骑士精神(BZOJ1085) 题解

【样例输入】

    2
    10110
    01*11
    10111
    01001
    00000
    01011
    110*1
    01110
    01010
    00100

【样例输出】

    7
    -1

【解题思路】

    这题为SCOI2005的题,首先看到这一题,以为是广搜,结果发现搜索树太大了,用队列会炸,于是想到了迭代加深。

    把答案作为加深的对象,不断的对答案+1,然后我们可以利用估价函数减小搜索的范围,其实就打一个深搜出来就行了。

【代码实现】

 

 1 const en:array[1..5] of string=('11111','01111','00*11','00001','00000');

 2       dx:array[1..8] of longint=(2,-2,1,1,-1,-1,2,-2);

 3       dy:array[1..8] of longint=(1,1,-2,2,-2,2,-1,-1);

 4 var a:array [1..5] of string[5];

 5     h,r,i,n,j,w,ans,mini,x,y:longint;

 6 procedure swap(var x,y:char);

 7 var ch:char;

 8 begin

 9  ch:=x;

10  x:=y;

11  y:=ch;

12 end;

13 procedure dfs(x,y,dep,last:longint);

14 var i,j,d,xx,yy:longint;

15 begin

16  d:=0;

17  if mini<>-1 then

18   exit;

19  for i:=1 to 5 do

20   for j:=1 to 5 do

21    if a[i,j]<>en[i,j] then

22     inc(d);

23  if d=0 then

24   begin

25    mini:=dep;

26    exit;

27   end;

28  if ans-dep<d-1 then

29   exit;

30  for i:=1 to 8 do

31   begin

32    if mini<>-1 then

33     break;

34    if i=9-last then

35     continue;

36    xx:=x+dx[i];

37    yy:=y+dy[i];

38    if (xx in[1..5])and(yy in[1..5]) then

39     begin

40      swap(a[x,y],a[xx,yy]);

41      dfs(xx,yy,dep+1,i);

42      swap(a[x,y],a[xx,yy]);

43     end;

44   end;

45 end;

46 begin

47  readln(w);

48  while w>0 do

49   begin

50    a[1]:='';a[2]:='';a[3]:='';a[4]:='';a[5]:='';

51    dec(w);

52    for i:=1 to 5 do

53     begin

54      readln(a[i]);

55      for j:=1 to 5 do

56       if a[i,j]='*' then

57        begin

58         x:=i;

59         y:=j;

60        end;

61     end;

62    mini:=-1;

63    for ans:=0 to 15 do

64     begin

65      dfs(x,y,0,-1);

66      if mini<>-1 then

67       break;

68     end;

69    if mini=-1 then

70     writeln(mini)

71    else

72     writeln(ans);

73   end;

74 end.

 

你可能感兴趣的:(ZOJ)