题目描述
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步
输入格式
一行四个数据,棋盘的大小和马的坐标
输出格式
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入输出样例
输入
3 3 1 1
输出
0 3 2
3 -1 1
2 1 4
解题思路
1、在搜索类型的题目中,类似于“最少要经历多少步”这样的问题时,首先应该想到使用BFS。
2、根据BFS的模板我们只需要分析,满足要求的结构体元素进入队列即可。
3、本题中使用vis判断输出的数据即可。vis[i][j]的值为0代表没有走过,vis[i][j]为-1代表是最初的起点,为其他数字就是代表到达该点最少的步数。
注意
1、输出要保证左对齐,并且宽五格。
2、马走“日”,要注意转移的位置坐标。
3、queue取队首元素使用的是front()而不是pop()。
完整代码
#include<bits/stdc++.h>
using namespace std;
int vis[410][410];//用于判断输出结果
int n,m;
int x[9]={0,1,2,2,1,-1,-2,-2,-1};//马走日,八个走向
int y[9]={0,2,1,-1,-2,-2,-1,1,2};
struct horse{
int x,y;
int step;//表示最少需要n步到达该点
}begin;
void bfs()
{
queue<horse>p;//创建队列
begin.step=0;//初始步数为0
p.push(begin);
vis[begin.x][begin.y]=-1;//起点设置为-1,用于判断
while(!p.empty())
{
horse a=p.front();//队列取首元素用front
p.pop();
int xx,yy;
for(int i=1;i<=8;i++)
{
xx=a.x+x[i];
yy=a.y+y[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&vis[xx][yy]==0)//如果可以走
{
horse b;
b.x=xx,b.y=yy;//创建结构体
vis[xx][yy]=a.step+1;
b.step=a.step+1; //一定要对结构体同时进行处理
p.push(b);//加入队列
}
}
}
}
int main()
{
scanf("%d %d %d %d",&n,&m,&begin.x,&begin.y);
bfs();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(vis[i][j]==-1)//如果是最初的起点
{
printf("%-5d",0);//输出靠左五个字符
}
else if(vis[i][j]==0)//如果没有走过
{
printf("%-5d",-1);
}
else printf("%-5d",vis[i][j]);//走过就输出最短
}
printf("\n");
}
return 0;
}