骑士问题(knight)

 骑士问题(knight)

题目描述

在一个标准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”标记的格子)。此外,骑士不能移出棋盘。
骑士可以按照移动规则自由地在棋盘上没有障碍物的格子中移动,图中给出了一个骑士移动的例子。初始格子用“n”标记,目标格子用“N”标记,有障碍物的格 子用“b”标记。一个可行的移动序列在图中用数字标记出来(al,b3,a5,c6,e5,94,h2,fl),总共需要7步才能完成。事实上,这也就是 最小的步数了。

输入

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

输出

对于每个数据,输出1行。格式:Board n:m moves,其中n表示数据的序号(从1开始),m表示骑士所用的最小的步数。如果骑士无法到达目标格子,输出:Board n:not reachable。

样例输入

8
c5 b4 c1 b2 e1 e5 f4 f2 
d3 h8
8
e8 e7 e6 e5 e4 e3 e2 e1
d3 h8
-1

样例输出

Board 1: not reachable
Board 2: 3 moves

标准的bfs搜索,这题发了wa两次,最后多测几组测试用例,发现没用完一次队列还有数据,需要清空。ac了,哈哈,

 

#include <cstdio>
#include <queue>
#include <cstring>
#include <map>
#define pi pair<int,int>
#define fi first
#define se second
#define mk make_pair
#include <cmath>
#include <algorithm>
using namespace std;
char maze[10][10];
char s[3],dr[3],orr[3];
const int inf= 0x3f3f3f3f;
int m,n,d[10][10];
int dx[8]={-2,-2,1,-1 ,2,2,-1,1},dy[8]={-1,1,2,2,-1,1,-2,-2};
queue<pi > que;
int bfs()
{
    while(!que.empty()) que.pop();
    memset(d,0x3f,sizeof(d));
    int drx=dr[1]-'0',dry=dr[0]-'a'+1,orx=orr[1]-'0',ory=orr[0]-'a'+1;
    d[drx][dry]=0;
    que.push(mk(drx,dry));
    while(!que.empty()){
        pi p = que.front();que.pop();
        if(p.fi==orx&&p.se==ory)    return d[orx][ory];

        for(int i=0;i<8;i++){
            int nx = p.fi+dx[i],ny = p.se+dy[i];

            if(nx>=1&&nx<=8&&ny>=1&&ny<=8&&d[nx][ny]==inf&&maze[nx][ny]!=1){
                d[nx][ny]=d[p.fi][p.se]+1;que.push(mk(nx,ny));
            }
        }
    }
    return -1;
}


int main()
{
    //freopen("data.in","r",stdin);
    int n,Case=0;
    while(scanf("%d",&n)){
        if(n==-1)break;
        Case++;
        memset(maze,0,sizeof(maze));
        //if(n==0)    printf("\n");
        for(int i=0;i<n;i++){
            scanf("%s",s);
            maze[s[1]-'0'][s[0]-'a'+1]=1;
        }
        scanf("%s%s",dr,orr);
        int ans=bfs();
        if(ans==-1) printf("Board %d: not reachable\n",Case);
        else  printf("Board %d: %d moves\n",Case,ans);

    }
}

 

posted on 2016-07-29 10:47  acmtime  阅读(1024)  评论(0编辑  收藏  举报

导航