P1443 马的遍历
题目描述
有一个 n \times mn×m 的棋盘,在某个点 (x, y)(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n, m, x,y。
输出格式
一个 n×m 的矩阵,代表马到达某个点最少要走几步(左对齐,宽 5 格,不能到达则输出 −1)。
输入输出样例
输入
3 3 1 1
输出
0 3 2
3 -1 1
2 1 4
代码实现
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
// 坐标向量
const int dx[10] = {-2, -2, 2, 2, 1, -1, 1, -1};
const int dy[10] = {-1, 1, -1, 1, 2, -2, -2, 2};
const int N = 500;
// 队列
typedef pair<int, int> PII;
int n, m, x, y;
int d[N][N]; // 是否走过
PII q[N * N]; // 存储数据队列
void bfs(int x, int y)
{
// 初始化
memset(d, -1, sizeof d); // -1 还没有走过
d[x][y] = 0; // 0 已经走过
// 初始化队列
queue<pair<int, int>> q;
q.push({x, y}); // 起始点入队
while (q.size())
{
PII t = q.front(); // 取出队头
q.pop(); // 出队
// 遍历八个方向
for (int i = 0; i < 8; i++)
{
int nx = t.first + dx[i], ny = t.second + dy[i]; // 扩展新点
if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && d[nx][ny] == -1) //没有超出棋盘并且没有走过
{
d[nx][ny] = d[t.first][t.second] + 1; // 到起点的距离
q.push({nx, ny}); // 加到队尾
}
}
}
}
int main()
{
cin >> n >> m >> x >> y;
bfs(x, y);
// 输出
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
printf("%-5d", d[i][j]);
puts("");
}
system("pause");
return 0;
}