문제 출처
1. 문제설명
NxN
크기의 맵이 주어진다.
- 각 칸은 1 또는 0으로 구성된다.
- 맵은 여러 개의 섬으로 구성되어 있다.
- 여기서 다리를 놓아 두 섬을 연결하고자 한다.
- 가장 짧은 다리의 길이를 구하라!
2. 알고리즘 설계
-
예를들어, 섬이 3개가 있다고 가정해보자.
1 1 1 0 0 0 0 1 1 1
1 1 1 1 0 0 0 0 1 1
1 0 1 1 0 0 0 0 1 1
0 0 1 1 1 0 0 0 0 1
0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0
-
각 섬을, 1, 2, 3번으로 구성한다.
1 1 1 0 0 0 0 2 2 2
1 1 1 1 0 0 0 0 2 2
1 0 1 1 0 0 0 0 2 2
0 0 1 1 1 0 0 0 0 2
0 0 0 1 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 0
0 0 0 0 3 3 0 0 0 0
0 0 0 0 3 3 3 0 0 0
0 0 0 0 0 0 0 0 0 0
- 각 섬에서 바다와 가장 인접한 칸부터 다른 섬을 만날 때까지 찾는다.
- for-loop로 (0,0)부터 시작하면 가장 처음 걸리는 칸은 (0,3)이 된다.
- 다른 섬과 가장 빠른 길(x로 표시)을 찾으면 4칸이다.
1 1 1 x x x x 2 2 2
1 1 1 1 0 0 0 0 2 2
1 0 1 1 0 0 0 0 2 2
0 0 1 1 1 0 0 0 0 2
0 0 0 1 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 0
0 0 0 0 3 3 0 0 0 0
0 0 0 0 3 3 3 0 0 0
0 0 0 0 0 0 0 0 0 0
- 위와 같은 식으로 모든 경로의 길이를 구한다.
- 가장 짧은 길이를 출력하면 된다.
3. 로직
- 각 섬에 번호를 매기는 방법은 두가지가 있다.
- bfs로 현재 1부터 0이 아닌 부분 전부 번호 매기기
- dfs로 현재 1부터 0이 아닌 부분 전부 번호 매기기
- 섬과 섬 간의 최단 거리는 BFS로 구해주었다.
- 상하좌우 한 칸씩 탐색을 하면서, 움직여 주면 된다.
- 주의할 점
- 섬과 섬 간의 거리를 구할 때, 방문 표시하는 배열과
- 처음 탐색 시작 위치를 방문 표시하는 배열을
- 별도로 두어야 한다.
4. 전체 코드
5. 기타
- 처음
get_distance()
에서 정답을 찾았을 때 외엔 반환을 하지 않았다.
- 그러나 다음 경우를 간과했다.
- 위 예시는 내 로직에 의하면 (1,1)에서 다른 섬으로 갈 수 있는지 시도한다.
- 그러나 다른 섬에 도착할 수가 없다.
- 그래서 시도하다가 큐가 비어버리고 처음 while-loop를 탈출하게 된다.
- 그래서 이미지와 같은 런타임 에러가 발생했다.
- 이 에러는 발생 원인이 여러가지가 있지만,
- 대표적인 것 중 하나로
main()
을 제외한 반환값이 있는 함수가 반환을 하지 않았을 때 라고 한다.