马的遍历
题目描述
有一个 n m的棋盘,在某个点 (x, y)$上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n, m, x, y。
输出格式
一个 n m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 -1)。
样例
样例输入
3 3 1 1
样例输出
0 3 2
3 -1 1
2 1 4
思路:
通过起点位置,开始遍历方向从第一个开始,若不满足则进行第二个方向,循环往后;若满足情况则将其作为新坐标然后继续往后方向遍历。(每次步数加1)
代码实现想法:
f存储步数
vis表示是否访问过
在函数外初始化变量,以及输入马可能走的位置。
一开始将步数设置为-1,该点是否被访问都为没有访问。
通过起点的数据开始,当前位置为访问过,当前位置步数设置为0,我们通过调用q.push(make_pair(x,y))来存储最开始的坐标。
接着进行判断该坐标是否为空判断循环终止。
若不为空则,从第一个方向开始遍历,与先前位置相加。并判断是否超过棋盘,是否访问过。将新的x,y进行存储,并且步数加1。
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int n,m,x,y;
//存储马可以走的位置
const int dx[8]={-1,-2,-2,-1,1,2,2,1};
const int dy[8]={2,1,-1,-2,2,1,-1,-2};
queue<pair<int,int>>q;
int f[500][500];//表示步数
int vis[500][500];//表示是否访问
int main()
{
int n,m,x,y;
memset(f,-1,sizeof(f));//初始化均为-1
memset(vis,false,sizeof(vis));//初始化均没有访问过
cin>>n>>m>>x>>y;
f[x][y]=0;
vis[x][y]=true;
q.push(make_pair(x,y));//存储两个int类型数据,这里相当于坐标
while(!q.empty())//当非空时运行
{
int xx=q.front().first;//表示存储坐标第一个元素
int yy=q.front().second;//同理
q.pop();//移除头元素
for(int i=0;i<8;i++)
{
int u=xx+dx[i];
int v=yy+dy[i];
if(u<1||u>n||v<1||v>m||vis[u][v])//判断是否超过棋盘或者访问过
{
continue;
}
vis[u][v]=true;//进行访问
q.push(make_pair(u,v));//将新的xy坐标放入
f[u][v]=f[xx][yy]+1;//走的步数加1
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%-5d",f[i][j]);
printf("\n");
}
return 0;
}