题目:
Description
有一个 �×�n×m 的棋盘,在某个点 (�,�)(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
Input
输入只有一行四个整数,分别为 �,�,�,�n,m,x,y。
Output
一个 �×�n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1−1)。
Sample 1
Inputcopy | Outputcopy |
---|---|
3 3 1 1 | 0 3 2 3 -1 1 2 1 4 |
Hint
数据规模与约定
对于全部的测试点,保证 1≤�≤�≤4001≤x≤n≤400,1≤�≤�≤4001≤y≤m≤400。
思路:
定义马的8个移动方向
int dx[8]={2,2,-2,-2,1,-1,1,-1};
int dy[8]={-1,1,-1,1,2,2,-2,-2};
初始化到每点的距离未无穷,除起点外,到起点的距离为0。
首先将起始位置加入队列,每次取出队首元素,对马从该点可以到达的,且从未被走过的点加入队列并更新到该点的距离,直到队列为空。
遍历每个点,若距离为INF则输出-1,否则输出相应的距离。
代码:
#include <cstdio>
#include<iostream>
#include<queue>
#define INF 1000000000
using namespace std;
typedef pair<int ,int> P;
int n,m,sx,sy;
int px,py;
int s[405][405];
//定义马的8个移动方向
int dx[8]={2,2,-2,-2,1,-1,1,-1};
int dy[8]={-1,1,-1,1,2,2,-2,-2};
int bfs()
{
//初始到达每点的距离为正无穷
for(int i = 0; i < 405 ;i++)
for(int j= 0; j < 405; j++)
s[i][j]=INF;
queue<P>que;
que.push(P(sx,sy));//将起始位置加入队列
s[sy][sx]=0;
//进行搜索
while(que.size())
{
P p = que.front();que.pop();
for(int i = 0; i < 8; i++)
{
int nx=p.first+dx[i],ny=p.second+dy[i];
if(nx>0&&nx<=n&&ny>0&&ny<=m&&s[ny][nx]==INF)
{
que.push(P(nx,ny));
s[ny][nx] = s[p.second][p.first]+1;
}
}
}
}
int main()
{
cin >>n >>m >>sx >>sy; //输入边界和位置
bfs();//进行bfs搜索
for(int i= 1;i <= n; i++)
{
for(int j = 1; j <= m ;j++)
{
if(s[j][i]!=INF)//如果马能够到达
printf("%-5d",s[j][i]);
else printf("-1 ");//不能则输出-1
}
printf("\n");
}
return 0;
}