大钉骑马走江湖(计蒜客 队列+bfs)

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

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

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

输入格式:

有多组测试样例。

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

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

输出格式:

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

样例输入

3 3
s..
...
..e

3 3
s#.
...
#.e

样例输出

4
-1

分析:这题我用的是宽搜和队列,做这题之前还不会队列,做了之后
发现队列和宽搜结合挺方便的。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<algorithm>
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;
	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&&
			   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]='1';
				}
				if(map[i][j]=='e')
				{
					end.x=i;
					end.y=j;
					map[i][j]='.';
				}
			}
		}
		start.step=0;
		printf("%d\n",bfs(start,end,map));
	}
	return 0;
}

  

队列的头文件:#include<queue>

创建一个队列:queue<int>q

下面是队列的一些函数






posted @ 2017-03-19 15:15  X_1996  阅读(333)  评论(0)    收藏  举报