• 40. 到达目的地的最短距离(第四期模拟笔试)


    链接:卡码网KamaCoder

    题目:

    样例:

    输入
    3
    输出
    3

    思路:

            这道题是求最少步数,联想一下 BFS,BFS 操作可得

    这是一个正向的 BFS

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define endl '\n'
    7. #define x first
    8. #define y second
    9. #define mk make_pair
    10. #define int long long
    11. #define NO puts("NO")
    12. #define YES puts("YES")
    13. #define umap unordered_map
    14. #define INF 0x3f3f3f3f3f3f3f3f
    15. #define All(x) (x).begin(),(x).end()
    16. #pragma GCC optimize(3,"Ofast","inline")
    17. #define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
    18. using namespace std;
    19. const int N = 2e6 + 10;
    20. using PII = pair<int, int>;
    21. int n;
    22. umap<int, bool>st; // 标记是否到达过的结点
    23. // 三个操作的遍历
    24. inline void op(queue<int>&q,int &now)
    25. {
    26. if (!st[now + 1])
    27. {
    28. st[now + 1] = true;
    29. q.emplace(now + 1);
    30. }
    31. if (!st[now - 1])
    32. {
    33. st[now - 1] = true;
    34. q.emplace(now - 1);
    35. }
    36. if (!st[now << 1])
    37. {
    38. st[now << 1] = true;
    39. q.emplace(now << 1);
    40. }
    41. }
    42. inline int BFS()
    43. {
    44. int step = 0;
    45. queue<int>q; // 建立队列
    46. q.emplace(0); // 存储起点
    47. while (q.size())
    48. {
    49. int sz = q.size();
    50. while (sz--)
    51. {
    52. int now = q.front(); // 取出当前结点
    53. q.pop();
    54. st[now] = true; // 标记当前结点
    55. if (now == n)
    56. return step; // 如果到达了终点返回步数
    57. // 遍历三个操作
    58. op(q,now);
    59. }
    60. ++step; // 步数累加
    61. }
    62. return -1; // 给定一个最终结果
    63. }
    64. inline void solve()
    65. {
    66. cin >> n;
    67. cout << BFS() << endl;
    68. }
    69. signed main()
    70. {
    71. // freopen("a.txt", "r", stdin);
    72. ___G;
    73. int _t = 1;
    74. // cin >> _t;
    75. while (_t--)
    76. {
    77. solve();
    78. }
    79. return 0;
    80. }

    提交后我们可以发现:

    内存超限了部分测试数据,关键点在于   操作 3 中 x = x * 2 使得 当某个数值的时候 ,使用操作3后,有可能 x > n 不必要的数据存储在了 q 中,这就是正向 BFS 的一个小缺陷

    我们可以试一下 反向BFS,以 终点 为起步存储点,往 0 方向操作,此时  now 应该被整除的时候,是最佳最少步数方案的,这样可以 避免 x = x * 2 中  x > n 的数据,节省了部分空间。

    代码详解如下:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define endl '\n'
    7. #define x first
    8. #define y second
    9. #define mk make_pair
    10. #define int long long
    11. #define NO puts("NO")
    12. #define YES puts("YES")
    13. #define umap unordered_map
    14. #define INF 0x3f3f3f3f3f3f3f3f
    15. #define All(x) (x).begin(),(x).end()
    16. #pragma GCC optimize(3,"Ofast","inline")
    17. #define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
    18. using namespace std;
    19. const int N = 2e6 + 10;
    20. using PII = pair<int, int>;
    21. int n;
    22. umap<int, bool>st; // 标记是否到达过的结点
    23. // 三个操作的遍历
    24. inline void op(queue<int>&q,int &now)
    25. {
    26. if (!st[now + 1])
    27. {
    28. st[now + 1] = true;
    29. q.emplace(now + 1);
    30. }
    31. if (!st[now - 1])
    32. {
    33. st[now - 1] = true;
    34. q.emplace(now - 1);
    35. }
    36. // 操作 3 中往 0 方向 走
    37. if (now % 2 == 0 && !st[now >> 1] )
    38. {
    39. st[now >> 1] = true;
    40. q.emplace(now >> 1);
    41. }
    42. }
    43. inline int BFS()
    44. {
    45. int step = 0;
    46. queue<int>q; // 建立队列
    47. q.emplace(n); // 存储起点, 将 n 作为起点
    48. while (q.size())
    49. {
    50. int sz = q.size();
    51. while (sz--)
    52. {
    53. int now = q.front(); // 取出当前结点
    54. q.pop();
    55. st[now] = true; // 标记当前结点
    56. if (!now)
    57. return step; // 如果到达了起点返回步数
    58. // 遍历三个操作
    59. op(q,now);
    60. }
    61. ++step; // 步数累加
    62. }
    63. return -1; // 给定一个最终结果
    64. }
    65. inline void solve()
    66. {
    67. cin >> n;
    68. cout << BFS() << endl;
    69. }
    70. signed main()
    71. {
    72. // freopen("a.txt", "r", stdin);
    73. ___G;
    74. int _t = 1;
    75. // cin >> _t;
    76. while (_t--)
    77. {
    78. solve();
    79. }
    80. return 0;
    81. }

    最后提交:

  • 相关阅读:
    01-Sentinel与spring-cloud的整合
    P10 属性分组
    javascript实现白平衡树 --- AVL 树
    装饰器模式:动态地添加功能
    算法与数据结构(二)————入门问题(最大利益问题)
    Windows 和 Linux 系统下,如何区分相同PID VID 的USB-HID设备
    【Python音视频技术】用moviepy实现图文成片功能
    数据库管理系统
    若依框架集成WebSocket带用户信息认证
    干货!BIM高性能3D Web轻量化引擎——HOOPS Communicator!
  • 原文地址:https://blog.csdn.net/hacker_51/article/details/133862567