https://www.luogu.org/problemnew/show/P1443
题目描述
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步
输入输出格式
输入格式:
一行四个数据,棋盘的大小和马的坐标
输出格式:
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入输出样例
输入样例#1: 复制
3 3 1 1
输出样例#1: 复制
0 3 2 3 -1 1 2 1 4
思路:跟平常的bfs没什么区别,只不过走的方式很特别,是象棋里面马走的方式,即‘日’字,改变一下数组就好了。
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
int vis[405][405]; //标记有没有走到过
int re[405][405]; //标记步数
int n,m,bx,by;
int d[8][2]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};
struct node
{
int x;
int y;
};
void bfs(int x,int y);
int main()
{
cin>>n>>m>>bx>>by;
memset(vis,0,sizeof(vis));
memset(re,-1,sizeof(re));
int step=0;
vis[bx][by]=1;//标记已经走过的点
re[bx][by]=0;
bfs(bx,by);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%-5d",re[i][j]);
cout<<endl;
}
return 0;
}
void bfs(int x,int y)
{
queue<node> q;
node temp1;
temp1.x=x;
temp1.y=y;
q.push(temp1);
while(!q.empty())
{
node temp2=q.front();
q.pop();
for(int i=0;i<8;i++)
{
int dx=temp2.x+d[i][0];
int dy=temp2.y+d[i][1];
if(dx<=0||dy<=0||dx>n||dy>m)
continue;
if(!vis[dx][dy]) //没有走到过
{
vis[dx][dy]=1;
temp1.x=dx;
temp1.y=dy;
q.push(temp1);//排到队列末尾
re[dx][dy]=re[temp2.x][temp2.y]+1;
}
}
}
}