정신과 시간의 방
작성일
2024. 11. 17. 23:01
작성자
risehyun
  • 문제

 

  • 풀이
#include <iostream>
#include <queue>
#include <string>
using namespace std;

int maze[102][102];
int dist[102][102];
int n, m;

int dx[4] = { -1, 1, 0, 0 };
int dy[4] = { 0, 0, -1, 1 };

int bfs() {
    queue<pair<int, int>> q;
    q.push({ 0, 0 });
    dist[0][0] = 1;

    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();

        for (int dir = 0; dir < 4; dir++) {
            int nx = x + dx[dir];
            int ny = y + dy[dir];

            if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
            if (dist[nx][ny] != 0) continue;
            if (maze[nx][ny] == 0) continue;

            dist[nx][ny] = dist[x][y] + 1;
            q.push({ nx, ny });
        }
    }

    return dist[n - 1][m - 1];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;

    for (int i = 0; i < n; i++) {
        string line;
        cin >> line;
        for (int j = 0; j < m; j++) {
            maze[i][j] = line[j] - '0';
        }
    }

    cout << bfs() << '\n';

    return 0;
}

 

  • 메모

2178번처럼 최단 거리의 경로를 구하는 문제의 경우 일반적으로 BFS 또는 다익스트라(가중치가 있는 경우)를 사용한다. 

여기서는 다음과 같은 이유 때문에 DFS의 사용이 적절치 않다. 

 

1) 한 경로를 끝까지 추적한 뒤에야 다른 경로를 탐색하기 때문에 첫 번째 시도한 경로가 최단 경로인지 보장할 수 없다. 

2) 경로가 여러 갈래인 경우 최장 경로를 먼저 갈 가능성도 존재하기 때문에 적절하지 않다. 

3) 불필요한 재귀함수를 사용하게 된다. 

 

구조적 바인딩(structured binding) 을 활용하면 아래 코드를 간략화할수 있다. 단, C++ 17 이후로 사용 가능하다.

 

- 원래 코드

pair<int, int> cur = q.front();
int cx = cur.first;
int cy = cur.second;

 

- 구조적 바인딩으로 간략화

auto [cx, cy] = q.front();

 

- 문법 예시

pair<int, int> p = {3, 7};
auto [a, b] = p;
cout << a << ", " << b << "\n"; // 3, 7