大钉骑马走江湖【bfs】

原题网址:http://nanti.jisuanke.com/t/11064

江湖是什么,对于在象棋界厮杀的大钉来说,江湖就是一个矩阵,他的目标,就是在江湖之中骑着马,从他的位置出发,走到终点。

当然,大钉的马也遵从中国象棋中的“马走日”的规则,而且在矩阵中,也会有一些障碍物,马不能跳到障碍物上;如果大钉的马面前有障碍物,即被“别马腿”,那么他将不能跳向有障碍物的左前和右前这两个方向。

请问最少需要多少步,大钉才能骑着马跳到终点。

输入格式:

有多组测试样例。

每组第一行输入两个数 nn 和 mm,代表矩阵的行数和列数,2 \leq n \leq m < 1002nm<100

接下来输入 nn 行字符串,其中 's' 代表起点,'e' 代表终点,'.' 代表空地,'#' 代表障碍物。

输出格式:

对应每组输入,输出骑马跳到终点的最小步数,如果跳不到终点,输出 -11

样例1

输入:

3 3
s..
...
..e

3 3
s#.
...
#.e

输出:

4
-1


题解:

不难想到bfs 暴力搜索的解法,象棋中“马战八方”,如果不考虑蹩腿和越界,至少要枚举八个位置,而这道题蹩马腿就是剪枝的条件了,特别注意常量数组的对应关系


/*
http://blog.csdn.net/liuke19950717
*/
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=105;
char map[maxn][maxn];
int n,m;
int  dh[8][2]={{-1,-2},{-1,2},{1,2},{1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
int dht[8][2]={{0,-1},{0,1},{0,1},{0,-1},{1,0},{1,0},{-1,0},{-1,0}};
struct node
{
	int x,y,time;
};
int bfs(int bx,int by,int ex,int ey)
{
	int vis[maxn][maxn]={0};
	queue<node> q;
	node st={bx,by,0};
	vis[bx][by]=1;
	q.push(st);
	while(!q.empty())
	{
		st=q.front();q.pop();
		if(st.x==ex&&st.y==ey)
		{
			return st.time;
		}
		for(int i=0;i<8;++i)
		{
			int tx=st.x+dh[i][0],ty=st.y+dh[i][1];
			if(tx<0||tx>=n||ty<0||ty>=m||map[tx][ty]=='#')
			{
				continue;
			}
			int sx=st.x+dht[i][0],sy=st.y+dht[i][1];
			if(map[sx][sy]=='#')
			{
				continue;
			}
			if(!vis[tx][ty])
			{
				vis[tx][ty]=1;
				node tp={tx,ty,st.time+1};
				q.push(tp);
			}
		}
	}
	return -1;
}
int main()
{
	while(~scanf("%d%d",&n,&m))
	{
		for(int i=0;i<n;++i)
		{
			scanf("%s",map[i]);
		}
		int bx,by,ex,ey;
		for(int i=0;i<n;++i)
		{
			for(int j=0;j<m;++j)
			{
				if(map[i][j]=='s')
				{
					bx=i;by=j;
				}
				else if(map[i][j]=='e')
				{
					ex=i;ey=j;
				}
			}
		}
		printf("%d\n",bfs(bx,by,ex,ey));
	}
	return 0;
}


你可能感兴趣的:(大钉骑马走江湖【bfs】)