• BFS专题5 跨步迷宫


    题目:

    样例1:

    输入
    1. 3 3
    2. 0 1 0
    3. 0 0 0
    4. 0 1 0

    输出
    3

     样例2:

    输入
    1. 3 3
    2. 0 1 0
    3. 0 1 0
    4. 0 1 0

    输出
    -1

    思路:

            这里的跨步迷宫,我们可以将移动坐标扩大一倍,即加上 {2,-2,0,0 }的移动坐标即可,特别需要注意的是,我们得到某个坐标后对它 / 2 判断该坐标是否可以走动,至于为什么要这样做,因为这样就可以判断跨步或者不跨步是否可以走动的条件 。

    代码详解如下:

    1. #include
    2. #define endl '\n'
    3. #define x first
    4. #define y second
    5. #define mk make_pair
    6. #define umap unordered_map
    7. #define ___G cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
    8. using namespace std;
    9. const int N = 500 + 10;
    10. using PII = pair<int,int>;
    11. int n,m;
    12. int g[N][N]; // 迷宫图
    13. bool vis[N][N]; // 标记是否走动过
    14. // 移动坐标
    15. int dx[8] = {1,-1,2,-2,0,0,0,0};
    16. int dy[8] = {0,0,0,0,1,-1,2,-2};
    17. // 判断走动条件
    18. inline bool isRun(int x,int y)
    19. {
    20. return (x >= 0 && x < n && y >= 0 && y < m && !g[x][y] && !vis[x][y]);
    21. }
    22. inline int BFS(int x,int y)
    23. {
    24. int step = 0;
    25. // 存储走动坐标
    26. queueq;
    27. // 存储起点 并标记
    28. q.push(mk(x,y));
    29. vis[x][y] = true;
    30. // 开始 BFS 走动
    31. // 这一层是走动的每一步
    32. while(q.size())
    33. {
    34. int sz = q.size();
    35. // 这一层是判断走动的方向
    36. while(sz--)
    37. {
    38. // 开始取出存储的走动坐标
    39. auto now = q.front();
    40. q.pop();
    41. // 如果当前坐标走到了出口,返回步数
    42. if(now.x == n - 1 && now.y == m - 1)
    43. {
    44. return step;
    45. }
    46. // 标记当前坐标
    47. vis[now.x][now.y] = true;
    48. // 判断走动的方向
    49. for(int i = 0;i < 8;++i)
    50. {
    51. // bx 和 by 是走动第一步下一个坐标
    52. int bx = now.x + dx[i];
    53. int by = now.y + dy[i];
    54. // tx 和 ty 是跨步的判断,
    55. // 这里 dx[i] / 2 有效的避免了数组越界
    56. int tx = now.x + (dx[i]>>1);
    57. int ty = now.y + (dy[i]>>1);
    58. // 如果可以走动第一步,并且也可以跨步
    59. if(isRun(bx,by) && !g[tx][ty])
    60. {
    61. // 存储该坐标 并标记
    62. q.push(mk(bx,by));
    63. vis[bx][by] = true;
    64. }
    65. }
    66. }
    67. // 开始走动累加步数
    68. ++step;
    69. }
    70. // 如果无法到达终点,返回 -1
    71. return -1;
    72. }
    73. inline void solve()
    74. {
    75. cin >>n >>m;
    76. for(int i = 0;i < n;++i)
    77. {
    78. for(int j = 0;j < m;++j)
    79. {
    80. cin >> g[i][j];
    81. }
    82. }
    83. cout << BFS(0,0) <
    84. }
    85. signed main()
    86. {
    87. ___G;
    88. // freopen("a.txt","r",stdin);
    89. int _t = 1;
    90. //cin >> _t;
    91. while(_t--)
    92. {
    93. solve();
    94. }
    95. return 0;
    96. }

    最后提交:

  • 相关阅读:
    微服务学习计划——消息队列
    C++11
    战队集结 蓄势而发 | 网安朝阳·西门子白帽黑客大赛
    贪心算法—活动选择问题
    性能测试-性能工程落地的4个阶段(21)
    Postman设置全局变量和传参
    240. 搜索二维矩阵 II Python
    自己动手写数据库:关系代数和查询树执行效率的推导
    (附源码)spring boot校园万能跑系统 毕业设计 160934
    获取JVM 进程 PID
  • 原文地址:https://blog.csdn.net/hacker_51/article/details/133266456