Notice
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 티스토리챌린지
- 라즈비안 os
- virtualbox
- bfg repo-cleaner
- mqtt
- ubuntu
- vm
- 통신 프로토콜
- mosquitto
- Git
- 리눅스
- 커밋 이력
- 스피커
- 마이크
- 보안
- 명령어
- Principles of Security
- 네트워크
- 라즈베리파이5
- linux
- IOT
- GitHub
- 오블완
- Type of Attacks
- 가상머신
- 부팅 스크립트
- 공유기 포트포워딩
Archives
신짱구의 개발일지
[알고리즘] DFS&BFS 문제: 미로 탈출 본문
문제 출처
[한빛미디어] 이것이 취업을 위한 코딩 테스트다 with 파이썬
문제 설명
동빈이는 N*M 크기의 직사각형 형태의 미로에 갇혔습니다. 미로에는 여러 마리의 괴물이 있어 이를 피해 탈출해야 합니다. 동빈이의 위치는 (1, 1)이며 미로의 출구는 (N, M)의 위치에 존재하며 한 번에 한 칸씩 이동할 수 있습니다. 이 때 괴물이 있는 부분은 0으로, 괴물이 없는 부분은 1로 표시되어 있습니다. 미로는 반드시 탈출할 수 있는 형태로 제시됩니다. 이때 동빈이가 탈출하기 위해 움직여야 하는 최소 칸의 개수를 구하세요. 칸을 셀 때는 시작 칸과 마지막 칸을 모두 포함해서 계산합니다.
문제 조건
- 입력 조건: 첫째 줄에 두 정수 N, M(4<=N, M<=200)이 주어집니다. 다음 N개의 줄에는 각각 M개의 정수(0 혹은 1)로 미로의 정보가 주어집니다. 각각의 수들은 공백 없이 붙어서 입력으로 제시됩니다. 또한 시작 칸과 마지막 칸은 항상 1입니다.
- 출력 조건: 첫째 줄에 최소 이동 칸의 개수를 출력합니다.
입력 예시
5 6
101010
111111
000001
111111
111111
출력 예시
10
문제 해결 아이디어
- BFS는 시작 지점에서 가까운 노드부터 차례대로 그래프의 모든 노드를 탐색합니다.
- 상, 하, 좌, 우로 연결된 모든 노드로의 거리가 1로 동일합니다.
- 따라서 (1, 1) 지점부터 BFS를 수행하여 모든 노드의 최단 거리 값을 기록하면 해결할 수 있습니다.
예시로 다음과 같이 3*3 크기의 미로가 있다고 가정합시다.
110
010
011
그래프로 표현하면 다음과 같다.
- 처음에 (1, 1)의 위치에서 시작합니다.
- (1, 1) 좌표에서 상, 하, 좌, 우로 탐색을 진행하면 바로 옆 노드인 (1, 2) 위치의 노드를 방문하게 되고 새롭게 방문하는 (1, 2) 노드의 값을 2로 바꾸게 됩니다.
- 마찬가지로 BFS를 계속 수행하면 결과적으로 다음과 같이 최단 경로의 값들이 1씩 증가하는 형태로 변경됩니다.
C++ 구현 코드
#include<iostream>
#include<queue>
using namespace std;
int n,m;
int graph[201][201];
// 이동할 네가지 방향 정의
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
int bfs(int x, int y) {
queue<pair<int, int>> q;
q.push({x, y});
// 큐가 빌 때까지 반복하기
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
// 현재 위치에서 4가지 방향으로의 위치 확인
for (int i=0; i<4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
// 미로 찾기 공간을 벗어난 경우 무시
if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
// 괴물인 경우 무시
if (graph[nx][ny] == 0) continue;
// 해당 노드를 처음 방문하는 경우에만 최단 거리 기록
if (graph[nx][ny] == 1) {
graph[nx][ny] = graph[x][y]+1;
q.push({nx, ny});
}
}
}
return graph[n-1][m-1];
}
int main() {
cin >> n >> m;
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
scanf("%1d", &graph[i][j]);
}
}
// 가장 오른쪽 아래까지의 최단 거리 반환
cout << bfs(0, 0) << endl;
return 0;
}
References
'알고리즘' 카테고리의 다른 글
[알고리즘] 순열(Permutation) (1) | 2024.09.10 |
---|---|
[알고리즘] DFS&BFS 문제: 음료수 얼려 먹기 (0) | 2024.08.24 |
[알고리즘] DFS(Depth First Search)이란? (0) | 2024.08.22 |
[알고리즘] BFS(Breadth First Search)이란? (0) | 2024.08.21 |
[알고리즘] 그래프 알고리즘(Graph Algorithm)이란? (0) | 2024.08.21 |