• 洛谷 P4554 小明的游戏


    思路:双端队列

    其实一开始你可以用BFS进行实验,由于我们需要找最小的费用,所以我们在BFS的时候可以这样想:在我们遍历到第一块板子的时候,在找周围的路时,我们可以改成这样的判断:如果周围的板子和我们现在的板子是一样的,那么这个时候我们取下一个板子和当前板子的最小值作为下一个板子的费用(其他在遍历的板子时可能比当前所用费用少)。可以这样想,但是有一个缺点,那就是当我们遍历完还要继续更新已经遍历完的格子,这样是不是会造成死循环而到达不到终点呢?是的,如果我们标记了状态,走过的格子我们已经走不了了;但是走过的格子还需要进行更新,所以这是矛盾的。我们需要想一种办法来解决这个问题。这就引出了这种做法,就是双端队列。

    我们当然是希望走到相同的板子上为好,因为这样费用才能达到最少,所以,我们的想法就是尽可能的先走完相同的格子,再去走不同的格子。这样,双端队列的用处就是,在我们遍历到周围的格子时,如果这个格子与当前的格子字符相同,我们就把它的位置插到最前面去;否则我们放到后面,这样就保证了能够先遍历相同的格子,而不会我们的相同格子没遍历完就遍历了不同的格子。

    上代码:

    1. #include<iostream>
    2. #include<stdio.h>
    3. #include<cstring>
    4. #include<cstdlib>
    5. #include<cmath>
    6. #include<vector>
    7. #include<algorithm>
    8. #include<stack>
    9. #include<queue>
    10. #include<deque>
    11. #include <iomanip>
    12. #include<sstream>
    13. #include<numeric>
    14. #include<map>
    15. #include<limits.h>
    16. #include<unordered_set>
    17. #include<set>
    18. #define int long long
    19. #define MAX 510
    20. #define _for(i,a,b) for(int i=a;i<(b);i++)
    21. #define ALL(x) x.begin(),x.end()
    22. using namespace std;
    23. typedef pair<int, int> PII;
    24. int n, m;
    25. int counts;
    26. int dx[] = { -1,1,0,0 };
    27. int dy[] = { 0,0,-1,1 };
    28. char maps[MAX][MAX];
    29. int dist[MAX][MAX];
    30. deque<PII>q;
    31. int stx, sty, edx, edy;
    32. int bfs(int x, int y) {
    33. q.push_back({ x,y });
    34. dist[x][y] = 0;
    35. while (!q.empty()) {
    36. auto tmp = q.front();
    37. q.pop_front();
    38. char ch = maps[tmp.first][tmp.second];
    39. _for(i, 0, 4) {
    40. int a = dx[i] + tmp.first;
    41. int b = dy[i] + tmp.second;
    42. if (a < 0 || a >= n || b < 0 || b >= m)
    43. continue;
    44. if (dist[a][b] >= 0)
    45. continue;
    46. if (maps[a][b] == ch)
    47. {
    48. dist[a][b] = dist[tmp.first][tmp.second];
    49. q.push_front({ a,b });
    50. }
    51. if (maps[a][b] != ch) {
    52. dist[a][b] = dist[tmp.first][tmp.second] + 1;
    53. q.push_back({ a,b });
    54. }
    55. if (a == edx && b == edy) {
    56. return dist[a][b];
    57. }
    58. }
    59. }
    60. return -1;
    61. }
    62. signed main() {
    63. ios::sync_with_stdio(false);
    64. cin.tie(NULL); cout.tie(NULL);
    65. while (cin>>n>>m,n||m) {
    66. _for(i, 0, n) {
    67. _for(j, 0, m)
    68. cin >> maps[i][j];
    69. }
    70. memset(dist, -1, sizeof dist);
    71. q.clear();
    72. cin >> stx >> sty >> edx >> edy;
    73. cout<<bfs(stx,sty)<<endl;
    74. }
    75. return 0;
    76. }

  • 相关阅读:
    基于openlayer展示mapbox样式的矢量切片
    京东云开发者|京东云RDS数据迁移常见场景攻略
    数据结构 图 并查集 遍历方法 最短路径算法 最小生成树算法 简易代码实现
    类加载子系统
    [c++]你最喜爱的stringstream和snprintf性能深入剖析
    黑客技术(网络安全)—高效自学
    如何在idea中创建一个SpringBoot项目(超详细教学)
    单片机涉及到这么多行业?
    《Python 密码学编程》读书笔记(2)
    【FusionInsight 迁移】HBase从C50迁移到6.5.1(03)6.5.1上准备Loader
  • 原文地址:https://blog.csdn.net/m0_73917165/article/details/137408194