题目链接:点击打开链接
描述:
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你点击打开链接计算出马到达棋盘上任意一个点最少要走几步
输入格式:一行四个数据,棋盘的大小和马的坐标
输出格式:
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入样例:
3 3 1 1
输出样例:0 3 2
3 -1 1
2 1 4
思路:
不能用dfs,那只会求到每一点的步数,而不是最快的步数,我用了bfs(广搜)寻找这一点能够到达的所有点,
非常标准的bfs,很容易写
code:
#include<iostream>
#include<cstring>//用到memset
#include<iomanip>//用到stew
using namespace std;
int s[402][402];//存取数据
int bx[401*401];//因为可能每个点都走,所以数组大一点
int by[401*401];
int fx[8]={-1,-2,-1,-2,1,2,1,2},//八个方向
fy[8]={2,1,-2,-1,2,1,-2,-1};//马走的方向
int n,m;//定义全局变量
void bfs(int x,int y);//寻找
void print();//输出
int main()
{
memset(s,-1,sizeof(s));//初始化
cin>>n>>m;
int x,y;
cin>>x>>y;
bfs(x,y);
print();//输出
return 0;
}
void print()
{
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
cout<<left<<setw(5)<<s[i][j];//左对齐,五位数
cout<<endl;
}
}
void bfs(int x,int y)
{
s[x][y]=0;
int dx,dy;
int head=0,tail=1;//初始化头,尾指针
bx[1]=x,by[1]=y;//记录下当前的位置
do
{
head++;//头指针加一,入库
for(int i=0;i<=7;++i)
{
dx=bx[head]+fx[i];//寻找方向
dy=by[head]+fy[i];
if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&s[dx][dy]<0)
//判断是否符合条件
{
++tail;//尾指针加一,更新队列
bx[tail]=dx;
by[tail]=dy;
s[dx][dy]=s[bx[head]][by[head]]+1;//前一步加一
}
}
}while(head<tail);
}