时间:1000ms 内存:32768k
江湖是什么,对于在象棋界厮杀的大钉来说,江湖就是一个矩阵,他的目标,就是在江湖之中骑着马,从他的位置出发,走到终点。
当然,大钉的马也遵从中国象棋中的“马走日”的规则,而且在矩阵中,也会有一些障碍物,马不能跳到障碍物上;如果大钉的马面前有障碍物,即被“别马腿”,那么他将不能跳向有障碍物的左前和右前这两个方向。
请问最少需要多少步,大钉才能骑着马跳到终点。
输入格式:
有多组测试样例。
每组第一行输入两个数 n 和 m,代表矩阵的行数和列数,2≤n≤m<100。
接下来输入 n 行字符串,其中 's' 代表起点,'e' 代表终点,'.' 代表空地,'#' 代表障碍物。
输出格式:
对应每组输入,输出骑马跳到终点的最小步数,如果跳不到终点,输出 −1。
样例1
输入:
3 3 s.. ... ..e 3 3 s#. ... #.e
输出:
4 -1
解题思路:类似于nyoj上的最小步,不过这里的特别之处在于,跳马走日,中间出现别马脚,第一次跳马之后,走过的点不可标记为障碍#,使用其他的特别符号,当在进行跳马判断是,只要别马腿处不是障碍物即可。
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int d[8][2]={-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2};
int pan[4][2]={-1,0,0,1,1,0,0,-1};
int m,n;
struct point
{
int x,y,step;
};
int bfs(point s,point t,char map[110][110])
{
queue<point>que;
int i;
point p;
que.push(s);
while(1)
{
if(s.x==t.x&&s.y==t.y)
return s.step;
for(i=0;i<8;++i)
{
p.x=s.x+d[i][0];
p.y=s.y+d[i][1];
int q = i/2;
int xtemp =s.x+pan[q][0];
int ytemp =s.y+pan[q][1];
if(p.x>=0&&p.x<n&&p.y>=0&&p.y<m&&xtemp>=0&&xtemp<n&&ytemp>=0&&ytemp<m&&map[p.x][p.y]=='.'&&map[xtemp][ytemp]!='#')
{
p.step=s.step+1;
map[p.x][p.y]='1';
que.push(p);
}
}
if(que.empty()){
return -1;
}
s=que.front();
que.pop();
}
}
int main()
{
int T;
point start ,end;
char map[110][110];
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
for(int i=0;i<n;i++)
{
scanf("%s",map[i]);
for(int j=0;j<m;j++)
{
if(map[i][j]=='s')
{
start.x=i;
start.y=j;
map[i][j]='.';
}
if(map[i][j]=='e')
{
end.x=i;
end.y=j;
map[i][j]='.';
}
}
}
map[start.x][start.y]='1';
start.step=0;
printf("%d\n",bfs(start,end,map));
}
return 0;
}