Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

경로를 생성하기 위해 그리드에서 차단할 셀의 수를 찾는 C++ 프로그램

<시간/>

h * w 차원의 그리드가 있다고 가정합니다. 셀 위치(0, 0)에 로봇이 있고 위치(h - 1, w - 1)로 이동해야 합니다. 그리드에는 차단된 것과 차단되지 않은 두 가지 유형의 셀이 있습니다. 로봇은 차단되지 않은 세포는 통과할 수 있지만 차단된 세포는 통과할 수 없습니다. 로봇은 4가지 방향으로 갈 수 있습니다. 왼쪽, 오른쪽, 위, 아래로 이동할 수 있습니다. 그러나 로봇은 한 셀에서 다른 셀로 임의의 방향으로 이동할 수 있으므로(이전 셀은 무시) 한 경로만 만들고 해당 경로에 없는 다른 모든 셀을 차단해야 합니다. 로봇이 (0, 0)에서 (h - 1, w - 1)까지 하나의 경로를 만들기 위해 차단해야 하는 셀 수를 찾아 반환해야 하며 가능한 경로가 없으면 -1을 반환합니다.

따라서 입력이 h =4, w =4, grid ={"..#.", "#.#.", "#.##", "#..."}인 경우 출력은 2가 됩니다.

경로를 생성하기 위해 그리드에서 차단할 셀의 수를 찾는 C++ 프로그램

(0, 0)에서 (3, 3)까지의 단일 경로를 생성하려면 두 개의 셀만 차단하면 됩니다.

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

Define one 2D array dp
dp[0, 0] := 0
Define an array moves containing pairs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
Define one queue q
insert pair (0, 0) at the end of q
while (not q is empty), do:
   p := first element of q
   delete first element from q
   for initialize i := 0, when i < 4, update (increase i by 1), do:
      row := first value of p + first value of moves[i]
      col := second value of p + second value of moves[i]
      if row < 0 or row > h - 1 or col < 0 or col > w - 1, then:
         Ignore following part, skip to the next iteration
      if grid[row, col] is same as '#', then:
         Ignore following part, skip to the next iteration
      if dp[first value of p, second value of p] + 1 < dp[row, col], then:
         dp[row, col] := dp[first value of p, second value of p] + 1
         insert pair(row, col) into q
if dp[h - 1, w - 1] is same as 2500, then:
   return -1
count := 0
   for initialize i := 0, when i < h, update (increase i by 1), do:
      for initialize j := 0, when j < w, update (increase j by 1), do:
      if grid[i, j] is same as '.', then:
         (increase count by 1)
return count - (dp[h - 1, w - 1] + 1)

예시

이해를 돕기 위해 다음 구현을 살펴보겠습니다. −

#include <bits/stdc++.h>
using namespace std;

int solve(int h, int w, vector<string> grid){
   vector<vector<int>> dp(h, vector<int>(w, 2500));
   dp[0][0] = 0;
   vector<pair<int, int>> moves = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
   queue<pair<int, int>> q;
   q.push(make_pair(0, 0));
   while (!q.empty()) {
      auto p = q.front();
      q.pop();
      for (int i = 0; i < 4; i++) {
         int row = p.first + moves[i].first;
         int col = p.second + moves[i].second;
         if (row < 0 || row > h - 1 || col < 0 || col > w - 1) continue;
         if (grid[row][col] == '#') 
            continue;
         if (dp[p.first][p.second] + 1 < dp[row][col]) {
            dp[row][col] = dp[p.first][p.second] + 1; q.push(make_pair(row, col));
         }
      }
   }
   if (dp[h - 1][w - 1] == 2500) {
      return -1;
   }
   int count = 0;
   for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
         if (grid[i][j] == '.') count++;
      }
   }
   return count - (dp[h - 1][w - 1] + 1);
}
int main() {
   int h = 4, w = 4;
   vector<string> grid = {"..#.", "#.#.", "#.##", "#..."};
   cout<< solve(h, w, grid);
   return 0;
}

입력

4, 4, {"..#.", "#.#.", "#.##", "#..."}

출력

2