fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. #include <string>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. int n, m;
  10. vector<string> grid;
  11. vector<vector<int>> distM, distA;
  12. vector<vector<pair<int, int>>> parent;
  13. vector<vector<char>> dir;
  14.  
  15. // Direction arrays for Up, Down, Left, Right
  16. int dr[] = {-1, 1, 0, 0};
  17. int dc[] = {0, 0, -1, 1};
  18. char move_dir[] = {'U', 'D', 'L', 'R'};
  19.  
  20. // Function to check if a cell is valid to move into
  21. bool isValid(int r, int c) {
  22. return (r >= 0 && r < n && c >= 0 && c < m && grid[r][c] != '#');
  23. }
  24.  
  25. int main() {
  26. // Optimize input/output operations
  27. ios_base::sync_with_stdio(false);
  28. cin.tie(NULL);
  29.  
  30. if (!(cin >> n >> m)) return 0;
  31.  
  32. grid.resize(n);
  33. distM.assign(n, vector<int>(m, 1e9)); // Initialize with a large number (infinity)
  34. distA.assign(n, vector<int>(m, 1e9));
  35. parent.assign(n, vector<pair<int, int>>(m, {-1, -1}));
  36. dir.assign(n, vector<char>(m, ' '));
  37.  
  38. queue<pair<int, int>> qM, qA;
  39. pair<int, int> startA;
  40.  
  41. // Read the grid and find the starting positions of the player and all monsters
  42. for (int i = 0; i < n; i++) {
  43. cin >> grid[i];
  44. for (int j = 0; j < m; j++) {
  45. if (grid[i][j] == 'M') {
  46. qM.push({i, j});
  47. distM[i][j] = 0;
  48. } else if (grid[i][j] == 'A') {
  49. startA = {i, j};
  50. qA.push({i, j});
  51. distA[i][j] = 0;
  52. }
  53. }
  54. }
  55.  
  56. // Step 1: Multi-source BFS for all monsters
  57. while (!qM.empty()) {
  58. auto [r, c] = qM.front();
  59. qM.pop();
  60.  
  61. for (int i = 0; i < 4; i++) {
  62. int nr = r + dr[i];
  63. int nc = c + dc[i];
  64.  
  65. // If the cell is valid and hasn't been visited by a monster yet
  66. if (isValid(nr, nc) && distM[nr][nc] == 1e9) {
  67. distM[nr][nc] = distM[r][c] + 1;
  68. qM.push({nr, nc});
  69. }
  70. }
  71. }
  72.  
  73. // Step 2: BFS for the Player 'A'
  74. bool possible = false;
  75. pair<int, int> end_pos = {-1, -1};
  76.  
  77. while (!qA.empty()) {
  78. auto [r, c] = qA.front();
  79. qA.pop();
  80.  
  81. // If 'A' has reached the boundary of the grid safely
  82. if (r == 0 || r == n - 1 || c == 0 || c == m - 1) {
  83. possible = true;
  84. end_pos = {r, c};
  85. break;
  86. }
  87.  
  88. for (int i = 0; i < 4; i++) {
  89. int nr = r + dr[i];
  90. int nc = c + dc[i];
  91.  
  92. if (isValid(nr, nc) && distA[nr][nc] == 1e9) {
  93. // 'A' can only step here if they get there faster than any monster
  94. if (distA[r][c] + 1 < distM[nr][nc]) {
  95. distA[nr][nc] = distA[r][c] + 1;
  96. parent[nr][nc] = {r, c}; // Track where we came from
  97. dir[nr][nc] = move_dir[i]; // Track what move we made to get here
  98. qA.push({nr, nc});
  99. }
  100. }
  101. }
  102. }
  103.  
  104. // Step 3: Print result and reconstruct the path
  105. if (possible) {
  106. cout << "YES\n";
  107. string path = "";
  108. int r = end_pos.first;
  109. int c = end_pos.second;
  110.  
  111. // Backtrack from the exit to the start point
  112. while (r != startA.first || c != startA.second) {
  113. path += dir[r][c];
  114. auto p = parent[r][c];
  115. r = p.first;
  116. c = p.second;
  117. }
  118.  
  119. // Reverse the path since we built it backwards
  120. reverse(path.begin(), path.end());
  121. cout << path.length() << "\n";
  122. cout << path << "\n";
  123. } else {
  124. cout << "NO\n";
  125. }
  126.  
  127. return 0;
  128. }
Success #stdin #stdout 0.01s 5316KB
stdin
5 8
########
#M..A..#
#.#.M#.#
#M#..#..
#.######
stdout
YES
5
RRDDR