• 骑士精神(BZOJ1085) 题解


    【问题描述】

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

    【样例输入】

        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.
  • 相关阅读:
    基数排序学习
    桶排序学习
    计数排序-不基于比较O(n)
    基尼系数
    拉普拉斯进行特征选择
    int ,long long等范围
    Codeforces780C
    51 Nod 1119
    字典树入门
    POJ 2531 暴力深搜
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4609396.html
Copyright © 2020-2023  润新知