P1443 马的遍历(BFS)

题目描述

有一个 n×m 的棋盘,在某个点 (x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。

输入格式

输入只有一行四个整数,分别为 n,m,x,y。

输出格式

一个 n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1)。

输入输出样例

输入 #1复制

3 3 1 1

输出 #1复制

0    3    2    
3    -1   1    
2    1    4    

说明/提示

数据规模与约定

对于全部的测试点,保证 1≤x≤n≤400,1≤y≤m≤400。

题目链接:P1443 马的遍历 - 洛谷 

学习链接:BFS习题课(上) | 从此搞懂搜索题的套路! | 入门必看_哔哩哔哩_bilibili

解题思路:

  1. 马走日,有八个方向可以走,设置一个方向数组 
  2. 马只能在n*m的矩阵里走,不能越界
  3. 设置一个距离数组dist[][],记录马从起点到某个点的距离
  4. 定义一个坐标队列 

代码如下: 

 

#include
using namespace std;
int n,m;//矩阵规模
int sx,sy;//起点 
int dist[405][405];//距离数组 
typedef pair PII;
queue q;
int x[8]={-2,-2,-1,1,2,2,1,-1};
int y[8]={-1,1,2,2,1,-1,-2,-2};
 
void bfs(int x1,int y1)
{
	//初始化距离数组dist
	memset(dist,-1,sizeof(dist));
	
	//将起点入队
	q.push({x1,y1});
	
	//记录起点距离
	dist[x1][y1]=0;
	
	//当队列不为空时
	while(!q.empty()) 
	{
		//取出队头
		PII t=q.front();
		//弹出 
		q.pop();
		
		//遍历队头的八个方向
		for(int i=0;i<8;i++)
		{
			//下一个试探的坐标
			int nx=t.first+x[i];
			int ny=t.second+y[i];
			
			//若坐标越界,跳过
			if(nx<1 || nx>n || ny<1 || ny>m)	continue;
			//坐标被记录过距离,跳过
			if(dist[nx][ny]!=-1)	continue;
			
			//若经过了重重考验
			//入队
			q.push({nx,ny});
			//计算距离:队头距离+1 
			dist[nx][ny]=dist[t.first][t.second]+1;	 
		} 
	}
	
	//全部遍历完毕,输出距离数组
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			printf("%-5d",dist[i][j]);   
		}
		printf("\n");	
	}
		
			
			
} 
int main()
{
	cin>>n>>m>>sx>>sy;
	bfs(sx,sy); 
	return 0;
} 

你可能感兴趣的:(算法,c++,宽度优先,蓝桥杯,数据结构)