|
| 1 | +--- |
| 2 | +title: 🐢 달이 차오른다, 가자 |
| 3 | +author: gani0325 |
| 4 | +date: 2024-01-21 20:00:00 +09:00 |
| 5 | +categories: [알고리즘, 달이 차오른다, 가자] |
| 6 | +tags: [알고리즘, 백준, 골드1, 그래프, 14주차, 이가은] |
| 7 | +render_with_liquid: false |
| 8 | +--- |
| 9 | + |
| 10 | +## 1. 문제 링크 |
| 11 | + |
| 12 | +[1194번: 달이 차오른다, 가자](https://www.acmicpc.net/problem/1194) |
| 13 | + |
| 14 | +<br> |
| 15 | + |
| 16 | +## 2. 코드 |
| 17 | + |
| 18 | +`Python3` `38828KB` `6168ms` |
| 19 | + |
| 20 | +```python |
| 21 | +""" |
| 22 | +[1194] 달이 차오른다, 가자 |
| 23 | +
|
| 24 | +💛 문제 |
| 25 | +지금 민식이가 계획한 여행은 달이 맨 처음 뜨기 시작할 때 부터, 준비했던 여행길이다. |
| 26 | +하지만, 매번 달이 차오를 때마다 민식이는 어쩔 수 없는 현실의 벽 앞에서 다짐을 포기하고 말았다. |
| 27 | +
|
| 28 | +민식이는 매번 자신의 다짐을 말하려고 노력했지만, 말을 하면 아무도 못 알아들을 것만 같아서, 지레 겁먹고 벙어리가 되어버렸다. |
| 29 | +결국 민식이는 모두 잠든 새벽 네시 반쯤 홀로 일어나, 창 밖에 떠있는 달을 보았다. |
| 30 | +
|
| 31 | +하루밖에 남지 않았다. 달은 내일이면 다 차오른다. 이번이 마지막기회다. 이걸 놓치면 영영 못간다. |
| 32 | +
|
| 33 | +영식이는 민식이가 오늘도 여태것처럼 그냥 잠 들어버려서 못 갈지도 모른다고 생각했다. |
| 34 | +하지만 그러기엔 민식이의 눈에는 저기 뜬 달이 너무나 떨렸다. |
| 35 | +
|
| 36 | +민식이는 지금 미로 속에 있다. 미로는 직사각형 모양이고, 여행길을 떠나기 위해 미로를 탈출하려고 한다. |
| 37 | +미로는 다음과 같이 구성되어져있다. |
| 38 | + 빈 칸: 언제나 이동할 수 있다. ('.') |
| 39 | + 벽: 절대 이동할 수 없다. ('#') |
| 40 | + 열쇠: 언제나 이동할 수 있다. 이 곳에 처음 들어가면 열쇠를 집는다. ('a', 'b', 'c', 'd', 'e', 'f') |
| 41 | + 문: 대응하는 열쇠가 있을 때만 이동할 수 있다. ('A', 'B', 'C', 'D', 'E', 'F') |
| 42 | + 민식이의 현재 위치: 빈 곳이고, 민식이가 현재 서 있는 곳이다. ('0') |
| 43 | + 출구: 달이 차오르기 때문에, 민식이가 가야하는 곳이다. 이 곳에 오면 미로를 탈출한다. ('1') |
| 44 | +
|
| 45 | +달이 차오르는 기회를 놓치지 않기 위해서, 미로를 탈출하려고 한다. |
| 46 | +한 번의 움직임은 현재 위치에서 수평이나 수직으로 한 칸 이동하는 것이다. |
| 47 | +
|
| 48 | +민식이가 미로를 탈출하는데 걸리는 이동 횟수의 최솟값을 구하는 프로그램을 작성하시오. |
| 49 | +
|
| 50 | +💚 입력 |
| 51 | +첫째 줄에 미로의 세로 크기 N과 가로 크기 M이 주어진다. (1 ≤ N, M ≤ 50) 둘째 줄부터 N개의 줄에 미로의 모양이 주어진다. |
| 52 | +같은 타입의 열쇠가 여러 개 있을 수 있고, 문도 마찬가지이다. |
| 53 | +그리고, 문에 대응하는 열쇠가 없을 수도 있다. '0'은 한 개, '1'은 적어도 한 개 있다. 열쇠는 여러 번 사용할 수 있다. |
| 54 | +
|
| 55 | +💙 출력 |
| 56 | +첫째 줄에 민식이가 미로를 탈출하는데 드는 이동 횟수의 최솟값을 출력한다. |
| 57 | +만약 민식이가 미로를 탈출 할 수 없으면, -1을 출력한다. |
| 58 | +""" |
| 59 | + |
| 60 | +from collections import deque |
| 61 | + |
| 62 | +# 세로 크기 N과 가로 크기 M |
| 63 | +n, m = map(int, input().split()) |
| 64 | +for _ in range(n) : |
| 65 | + maze = list(map(str, input().split())) |
| 66 | + |
| 67 | +dx = [1, -1, 0, 0] |
| 68 | +dy = [0, 0, -1, 1] |
| 69 | + |
| 70 | +visited = [[[0] for _ in range(m)] for _ in range(n)] |
| 71 | +queue = deque() |
| 72 | + |
| 73 | +# 빈 칸: 언제나 이동할 수 있다. ('.') |
| 74 | +# 벽: 절대 이동할 수 없다. ('#') |
| 75 | +# 열쇠: 언제나 이동할 수 있다. 이 곳에 처음 들어가면 열쇠를 집는다. ('a', 'b', 'c', 'd', 'e', 'f') |
| 76 | +# 문: 대응하는 열쇠가 있을 때만 이동할 수 있다. ('A', 'B', 'C', 'D', 'E', 'F') |
| 77 | +# 민식이의 현재 위치: 빈 곳이고, 민식이가 현재 서 있는 곳이다. ('0') |
| 78 | +# 출구: 달이 차오르기 때문에, 민식이가 가야하는 곳이다. 이 곳에 오면 미로를 탈출한다. ('1') |
| 79 | +for i in range(n): |
| 80 | + for j in range(m): |
| 81 | + # 시작 좌표 |
| 82 | + if maze[i][j] == "0": |
| 83 | + # 좌표, key |
| 84 | + queue.append([i, j, 0]) |
| 85 | + # 빈칸으로 . |
| 86 | + maze[i][j] = "." |
| 87 | + # 방문함 |
| 88 | + visited[i][j][0] = 1 |
| 89 | + |
| 90 | +while queue : |
| 91 | + x, y, k = queue.popleft() |
| 92 | + |
| 93 | + # 출구, 미로 탈출하기 |
| 94 | + if maze[x][y] == "1" : |
| 95 | + answer = visited[x][y] - 1 |
| 96 | + break |
| 97 | + |
| 98 | + for i in range(4) : |
| 99 | + nx = x + dx[i] |
| 100 | + ny = y + dy[i] |
| 101 | + |
| 102 | + # 범위 안, 방문 안함 벽 아님 |
| 103 | + if (0 <= nx < n and 0 <= ny < m and visited[x][y] == 0 and maze[nx][ny] != "#") : |
| 104 | + # 열쇠 |
| 105 | + if maze[nx][ny] in ['a', 'b', 'c', 'd', 'e', 'f'] : |
| 106 | + visited[x][y] = visited[nx][ny] + 1 |
| 107 | + queue.append((nx, ny, k)) |
| 108 | + # 문 |
| 109 | + elif maze[nx][ny] in ['A', 'B', 'C', 'D', 'E', 'F'] : |
| 110 | + visited[x][y] = visited[nx][ny] + 1 |
| 111 | + queue.append((nx, ny, k)) |
| 112 | + # 길 |
| 113 | + else : |
| 114 | + visited[x][y] = visited[nx][ny] + 1 |
| 115 | + queue.append((nx, ny, k)) |
| 116 | + |
| 117 | +print(answer) |
| 118 | + |
| 119 | +``` |
| 120 | + |
| 121 | +<br> |
| 122 | + |
| 123 | +## 3. 해설 |
0 commit comments