题目描述
有一个 𝑛×𝑚n×m 的棋盘,在某个点 (𝑥,𝑦)(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 𝑛,𝑚,𝑥,𝑦n,m,x,y。
输出格式
一个 𝑛×𝑚n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1−1)。
输入输出样例
输入 #1复制
3 3 1 1
输出 #1复制
0 3 2 3 -1 1 2 1 4
说明/提示
数据规模与约定
对于全部的测试点,保证 1≤𝑥≤𝑛≤4001≤x≤n≤400,1≤𝑦≤𝑚≤4001≤y≤m≤400。
思路
首先马所在的位置是不需要走的,所有为0;
而从零开始走,能到地方肯定为0 + 1;
而从0 + 1 地方走的 肯定是 在它的基础上在加一, 即 0 + 1 + 1;
很容易发现,这个是先看第一步 ,第一步完了才是第二步…………
这个是深度优先搜索(bfs)
那这一题就简单了,先把点放进队列里面,通过先进先出的特性,来进行
代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N = 401;
int dx[] = {-1, -2, -2, -1, 1, 2, 2, 1};
int dy[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int v[N][N];
int map[N][N];
int n, m;
void bfs(int x, int y){
queue<pair<int,int> >q;
// s.push(make_pair(x, y));//这个和q.push({x, y});都是一样的效果
q.push({x, y});
map[x][y] = 0;//马所在的位置为0;
v[x][y] = 1;//标记是否到达
while(!q.empty()){
int xx = q.front().first;//x
int yy = q.front().second;/y
q.pop();//出队
for (int i = 0; i < 8; i ++){
//向外延伸的点x和y
int x2 = xx + dx[i];
int y2 = yy + dy[i];
if (x2 > 0 && x2 <= n && y2 > 0 && y2 <= m && !v[x2][y2]){
map[x2][y2] = map[xx][yy] + 1;//这个点等于上一个点加一
v[x2][y2] = 1;//标记
q.push({x2, y2});//入队
}
}
}
}
int main(){
int x, y;
cin >> n >> m >> x >> y;
memset(map, -1, sizeof map);
memset(v, 0, sizeof v);
bfs(x, y);
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= m; j ++){
cout << map[i][j] << " ";
}
cout << endl;
}
return 0;
}