洛谷P1443题解

这道题主要用到了bfs(广度优先搜索) 用dfs(深度优先搜索)也可以 ,但有一个点会超时(别问我是怎么知道的)

说到bfs 我们可以使用一个队列,不断搜索当前数据周围的数据;并将其入队,由于队列是先进先出型,因此最先进入的元素会先出队,这样就确保了不断在中心元素周围搜索,类似涟漪一样,而不是像dfs那样一条路一条路搜索,节省了许多时间。

现在我们回到本题,我们的思路主要是先搜索给定点周围的8个位置,并判断那些位置是可行的,然后依次搜索这些位置周围的位置,直到所有能搜索的位置都已被搜索到。首先,我们需要定义一个二维数组,并对其赋初值为-1;这里可以用到memset函数,然后将题目给出的坐标入队,然后不断搜索,并按照其从原点经过几次到达某位置对该坐标对应的二维数组赋值,并在元素被搜索完后弹出队列,直到队列为空时停止循环。关于队列,头文件为include <queue>

定义方法为queue <int>p;

p即为一个队列

下面附上一些函数

  1. push() 在队尾插入一个元素
  2. pop() 删除队列第一个元素
  3. size() 返回队列中元素个数
  4. empty() 如果队列空则返回true
  5. front() 返回队列中的第一个元素
  6. 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;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值