这道题主要用到了bfs(广度优先搜索) 用dfs(深度优先搜索)也可以 ,但有一个点会超时(别问我是怎么知道的)
说到bfs 我们可以使用一个队列,不断搜索当前数据周围的数据;并将其入队,由于队列是先进先出型,因此最先进入的元素会先出队,这样就确保了不断在中心元素周围搜索,类似涟漪一样,而不是像dfs那样一条路一条路搜索,节省了许多时间。
现在我们回到本题,我们的思路主要是先搜索给定点周围的8个位置,并判断那些位置是可行的,然后依次搜索这些位置周围的位置,直到所有能搜索的位置都已被搜索到。首先,我们需要定义一个二维数组,并对其赋初值为-1;这里可以用到memset函数,然后将题目给出的坐标入队,然后不断搜索,并按照其从原点经过几次到达某位置对该坐标对应的二维数组赋值,并在元素被搜索完后弹出队列,直到队列为空时停止循环。关于队列,头文件为include <queue>
定义方法为queue <int>p;
p即为一个队列
下面附上一些函数
- push() 在队尾插入一个元素
- pop() 删除队列第一个元素
- size() 返回队列中元素个数
- empty() 如果队列空则返回true
- front() 返回队列中的第一个元素
- back() 返回队列中最后一个元素
但由于本题的坐标是二维的,定义的也是二维数组,但队列只能存一个数,那我们该怎么将坐标存入队列呢?
这里我用的方法是定义两个队列,分别存储下x,y坐标
然后就是不断搜索,如果搜索的位置存在且未被搜索过(c[a][b]=-1因为被搜索的位置都已被赋值)存入队尾,重复操作直至队列为空。
下面附上代码
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
queue<int>q;//两个队列对应两个坐标
queue<int>p;
int c[401][401];//定义二维数组来模拟坐标
int main()
{
int n, m, x, y;
cin >> n >> m >> x >> y;
q.push(x);
p.push(y);
memset(c, -1, sizeof(c));//对数组c进行赋值
c[x][y] = 0;//对原点赋值
while (p.size() > 0)
{
if (q.front() + 2 <= n && p.front() + 1 <= m && c[q.front() +2][p.front() + 1] == -1)//搜索位置是否满足条件
{
q.push(q.front() + 2);//入队
p.push(p.front() + 1);
c[q.front() + 2][p.front() + 1] = c[q.front()][p.front()] + 1;//表示其是在原点经过几次搜索后入队的,并用此值标记其是否被搜索过
}
if (q.front() + 2 <= n && p.front() - 1 >= 1 && c[q.front() + 2][p.front() - 1] == -1 )
{
q.push(q.front() + 2);
p.push(p.front() - 1);
c[q.front() + 2][p.front() - 1] = c[q.front()][p.front()] + 1;
}
if (q.front() - 2 >= 1 && p.front() + 1 <= m && c[q.front() - 2][p.front() + 1] == -1 )
{
q.push(q.front() - 2);
p.push(p.front() + 1);
c[q.front() - 2][p.front() + 1] = c[q.front()][p.front()] + 1;
}
if (q.front() - 2 >= 1 && p.front() - 1 >= 1 && c[q.front() - 2][p.front() - 1] == -1 )
{
q.push(q.front() - 2);
p.push(p.front() - 1);
c[q.front() - 2][p.front() - 1] = c[q.front()][p.front()] + 1;
}
if (p.front() + 2 <= m && q.front() + 1 <= n && c[q.front() + 1][p.front() + 2] == -1 )
{
q.push(q.front() + 1);
p.push(p.front() + 2);
c[q.front() + 1][p.front() + 2] = c[q.front()][p.front()] + 1;
}
if (p.front() + 2 <= m && q.front() - 1 >= 1 && c[q.front() - 1][p.front() + 2] == -1 )
{
q.push(q.front() -1);
p.push(p.front() + 2);
c[q.front() -1][p.front() + 2] = c[q.front()][p.front()] + 1;
}
if (p.front() - 2 >= 1 && q.front() + 1 <= n && c[q.front() + 1][p.front() - 2] == -1 )
{
q.push(q.front() +1);
p.push(p.front() -2);
c[q.front() + 1][p.front() -2] = c[q.front()][p.front()] + 1;
}
if (p.front() - 2 >= 1 && q.front() - 1 >= 1 && c[q.front() - 1][p.front() - 2] == -1 )
{
q.push(q.front() -1);
p.push(p.front() -2);
c[q.front() -1][p.front() -2] = c[q.front()][p.front()] + 1;
}
q.pop();//出队
p.pop();
}
for (int i = 1; i <= n; i++)//输出数组
{
for (int j = 1; j <= m; j++)
cout << c[i][j] << " ";
cout << '\n';
}
return 0;
}