题目描述
有一个 n×mn \times mn×m 的棋盘,在某个点 (x,y)(x, y)(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n,m,x,yn, m, x, yn,m,x,y。
输出格式
一个 n×mn \times mn×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1-1−1)。
输入输出样例 #1
输入 #1
3 3 1 1
输出 #1
0 3 2
3 -1 1
2 1 4
说明/提示
数据规模与约定
对于全部的测试点,保证 1≤x≤n≤4001 \leq x \leq n \leq 4001≤x≤n≤400,1≤y≤m≤4001 \leq y \leq m \leq 4001≤y≤m≤400。
2022 年 8 月之后,本题去除了对输出保留场宽的要求。为了与之兼容,本题的输出以空格或者合理的场宽分割每个整数都将判作正确。
solution
用广度优先搜索,从起点开始将马一步能到的地方搜索出来,并从一步到的位置搜索两步到的位置、依次类推
代码
#include <sstream>
#include "iostream"
#include "math.h"
#include "algorithm"
#include "string.h"
#include "unordered_set"
#include "deque"
#include "stack"
#include "queue"
#include "vector"
#include "unordered_map"
using namespace std;
const int N = 4e2 + 1;
int a[N][N];
int dx[] = {1, 1, -1, -1, 2, 2, -2, -2};
int dy[] = {2, -2, 2, -2, -1, 1, -1, 1};
int main() {
int m, n, x, y;
cin >> m >> n >> x >> y;
memset(a, -1, sizeof(a));
a[x][y] = 0;
queue<int> qx, qqx;
queue<int> qy, qqy;
qx.push(x);
qy.push(y);
int xx, yy;
int step = 1;
while (true) {
while (!qx.empty()) {
int x1 = qx.front();
qx.pop();
int y1 = qy.front();
qy.pop();
for (int i = 0; i < 8; i++) {
xx = x1 + dx[i];
yy = y1 + dy[i];
if (xx <= m && xx >= 1 && yy >= 1 && yy <= n) {
if (a[xx][yy] == -1) {
a[xx][yy] = step;
//cout << xx << " " << yy << " " << step << endl;
qqx.push(xx);
qqy.push(yy);
}
}
}
}
step++;
qx = qqx;
qy = qqy;
qqx = queue<int>();
qqy = queue<int>();
if (qx.empty()) break;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++)
cout << a[i][j] << " ";
cout << endl;
}
return 0;
}