洛谷 P1443 马的遍历

到达某个点最少走几步,涉及广度优先搜索(BFS),要用到队列。

洛谷 P1443 马的遍历_第1张图片

做题思路:

洛谷 P1443 马的遍历_第2张图片 

由输出的矩阵看出这个马只能按照象棋中的走法跳,由此可以定义一个移动的数组:

int dir[8][2]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};//可以跳八个方向

不能到达则输出 -1,那么可以用数组标记

bool vis[410][410];

不用数组标记也可以直接把矩阵初始化为-1,可用双重for循环,也可以用memset函数

int mp[410][410];//矩阵

memset(mp,-1,sizeof(mp));//将mp[][]初始化为-1

因为是一层层搜索,可以直接得到最短步数用mp[][]来记录,不用额外定义变量记录最短步数

for(int i=0;i<8;i++)//八个方向 
{
	int nx = S.front().zx + dir[i][0];
	int ny = S.front().zy + dir[i][1];
	if( nx>=1 && nx<=n && ny>=1 && ny<=m && mp[nx][ny]==-1 )
//一层层搜该层的点八个方向可以到达且没有到过的点 
	{
		S.push((Node){nx,ny,S.front().step+1});
		mp[nx][ny]=S.front().step+1;
//记录到达该点所用步数,并且可使下层搜索不再搜索到该点,即已得到最短步数 
	}
}

洛谷 P1443 马的遍历_第3张图片

 洛谷 P1443 马的遍历_第4张图片

 洛谷 P1443 马的遍历_第5张图片

 两组数据测试完没问题,结果交上去全WA,然后发现格式不对,场宽5注意到了,没注意到左对齐

洛谷 P1443 马的遍历_第6张图片

 这下OK了

#include
#include
#include//memset()要用到的头文件 
#include//setw()要用到的头文件 
using namespace std;
int n,m,x,y;//1≤x≤n≤400,1≤y≤m≤400
int mp[410][410];//矩阵
int dir[8][2]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};//可以跳八个方向 

struct Node//定义个结构体储存变量用到队列中 
{
	int zx,zy,step;
 } ;

int main()
{
	cin>>n>>m>>x>>y;
	memset(mp,-1,sizeof(mp));
	mp[x][y]=0;
	
	queue < Node > S;
	S.push((Node){x,y,0});
	while(!S.empty())
	{
		for(int i=0;i<8;i++)//八个方向 
		{
			int nx = S.front().zx + dir[i][0];
			int ny = S.front().zy + dir[i][1];
			if( nx>=1 && nx<=n && ny>=1 && ny<=m && mp[nx][ny]==-1 )//一层层搜该层点八个方向可以到达且没有到过的点 
			{
				S.push((Node){nx,ny,S.front().step+1});
				mp[nx][ny]=S.front().step+1;//记录到达该点所用步数,并且可使下层搜索不再搜索到该点,即已得到最短步数 
			}
		}
		S.pop();
	}
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cout<

洛谷 P1443 马的遍历_第7张图片

你可能感兴趣的:(搜索,c++,算法,bfs)