【GDOI2003】骑士问题 {广度优先搜索}

题目

Description
  在一个标准8*8的国际象棋棋盘上,棋盘中有些格子可能是有障碍物的。已知骑士的初始位置和目标位置,你的任务是计算骑士最少需要多少步可以从初始位置到达目标位置。有障碍物的格子当然不可以到达。
  标准的8*8的国际象棋中每一个格子可以用唯一的编号确定。行用1-8这8个数字依次表示,列用’a’-’h’这8个字母依次表示。例如左下图的骑士所在位置(图中有n的格子)的编号为“d4”(注意‘d’和‘4’之间没有空格)。   
  我们知道国际象棋中的骑士可以按“L”路线移动(一个方向走2个格子,接着垂直方向走1个格子)。因此,如左上图中的骑士(位于d4),可以到达位置c2,b3,b5,c6,e6,f5,f3,e2(图中有‘x’标记的格子)。此外,骑士不能够移出棋盘。
  《【GDOI2003】骑士问题 {广度优先搜索}》
  骑士可以按照移动规则自由地在棋盘上没有障碍物的格子中移动。右上图给出了一个骑士移动的例子。初始格子用‘n’标记,目标格子用‘N’标记,有障碍物的格子用‘b’标记。一个可行的移动序列在图中用数字标记出来。(a1,b3,a5,c6,e5,g4,h2,f1)。总共需要7步才能完成。事实上,这也就是最小的步数了。

Input
  输入文件包括1个或多个测试数据。
  每一个测试数据的第一行是一个整数b(-1<=b<=62),表示棋盘中有障碍物的格子数目,当b=-1时,输入文件结束。
  第二行含b个不同的障碍物的格子编号,用空格隔开。当b=0时,此行为空行。
  第三行是骑士的初始格子和目标格子的编号,也是用空格隔开。初始格子和目标格子是不同的,且都没有障碍物。

Output
  对于每个数据,输出对应的d(p)。所有数据的结果都输出到一行中,用逗号分开。
 

解题思路

一道广度优先搜索的模板题,把障碍物当做已经搜过的点就可以了

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
using namespace std; 
const int xx[8]={2,1,-1,-2,-2,-1,1,2},yy[8]={1,2,2,1,-1,-2,-2,-1};
struct node{
    int q,w; 
}d[101];
int b,len,ans,head,tail,x[2],y[2],fa[101]; bool a[9][9]; 
void bfs()
{
        do
        {
            head++; 
            for (int i=0;i<8;i++)
            {
             int u=d[head].q+xx[i],e=d[head].w+yy[i]; 
             if (u>=1&&u<=8&&e>=1&&e<=8&&a[u][e]==0)
             {
                fa[++tail]=head; a[u][e]=1; 
                if (u==x[1]&&e==y[1]) return;
                d[tail].q=u; d[tail].w=e; 
             }
            }
        } while (head<tail);    
}
int frr(int tail)
{ if (fa[tail]!=0) frr(fa[tail]); ans++; return ans; }
int main()
{
    while (1)
    {
        scanf("%d",&b); 
        if (b==-1) return 0; else len++; 
        memset(a,0,sizeof(a)); 
        memset(d,0,sizeof(d)); 
        memset(fa,0,sizeof(fa)); 
        string s; ans=0; 
        for (int i=1;i<=b;i++)
         {
            cin>>s; 
            a[s[0]-96][s[1]-48]=1; 
         }
        cin>>s; x[0]=s[0]-96; y[0]=s[1]-48; 
        cin>>s; x[1]=s[0]-96; y[1]=s[1]-48; 
        d[1].q=x[0]; d[1].w=y[0]; a[x[0]][y[0]]=1; 
        head=0; tail=1; 
        bfs(); 
        if (a[x[1]][y[1]]==1) printf("Board %d: %d moves\n",len,frr(tail)-1); 
         else printf("Board %d: not reachable\n",len); 
    }
}
    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/qq_39897867/article/details/80972255
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞