Skip to content

Commit 68ebf48

Browse files
committed
[Gold III] Title: 벽 부수고 이동하기 2, Time: 1904 ms, Memory: 956036 KB -BaekjoonHub
1 parent 75c46f1 commit 68ebf48

2 files changed

Lines changed: 95 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# [Gold III] 벽 부수고 이동하기 2 - 14442
2+
3+
[문제 링크](https://www.acmicpc.net/problem/14442)
4+
5+
### 성능 요약
6+
7+
메모리: 956036 KB, 시간: 1904 ms
8+
9+
### 분류
10+
11+
그래프 이론, 그래프 탐색, 너비 우선 탐색, 격자 그래프
12+
13+
### 제출 일자
14+
15+
2025년 8월 28일 14:48:17
16+
17+
### 문제 설명
18+
19+
<p>N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다.</p>
20+
21+
<p>만약에 이동하는 도중에 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, 벽을 K개 까지 부수고 이동하여도 된다.</p>
22+
23+
<p>한 칸에서 이동할 수 있는 칸은 상하좌우로 인접한 칸이다.</p>
24+
25+
<p>맵이 주어졌을 때, 최단 경로를 구해 내는 프로그램을 작성하시오.</p>
26+
27+
### 입력
28+
29+
<p>첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 1,000), K(1 ≤ K ≤ 10)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.</p>
30+
31+
### 출력
32+
33+
<p>첫째 줄에 최단 거리를 출력한다. 불가능할 때는 -1을 출력한다.</p>
34+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
let nmk = readLine()!.split { $0 == " " }.map { Int(String($0))! },
2+
n = nmk[0], //행갯수
3+
m = nmk[1], //열갯수
4+
k = nmk[2] //부술수 있는 벽갯수
5+
6+
var map = [[Int]]()
7+
var isVisited = [[[Bool]]](
8+
repeating: [[Bool]](repeating: [Bool](repeating: false, count: k+1), count: m),
9+
count: n
10+
)
11+
var answer = Int.max
12+
13+
for _ in 0..<n {
14+
let line = readLine()!.map { Int(String($0))! }
15+
map.append(line)
16+
}
17+
18+
struct Point {
19+
let r: Int
20+
let c: Int
21+
let moveCount: Int
22+
let breakCount: Int
23+
}
24+
let dc = [0, 0, -1, 1]
25+
let dr = [-1, 1, 0, 0]
26+
27+
func bfs() {
28+
let firstMove = Point(r: 0, c: 0, moveCount: 0, breakCount: 0)
29+
var queue = [firstMove]
30+
isVisited[0][0][0] = true
31+
var index = 0
32+
33+
while queue.count > index {
34+
let currentPoint = queue[index]
35+
if currentPoint.r == n-1, currentPoint.c == m-1 {
36+
index += 1
37+
answer = answer > currentPoint.moveCount ? currentPoint.moveCount : answer
38+
return
39+
}
40+
for i in 0..<4 {
41+
let nc = currentPoint.c + dc[i]
42+
let nr = currentPoint.r + dr[i]
43+
guard (0..<n).contains(nr), (0..<m).contains(nc) else { continue }
44+
guard !isVisited[nr][nc][currentPoint.breakCount] else { continue }
45+
if map[nr][nc] == 1 {
46+
let nb = currentPoint.breakCount + 1
47+
guard nb <= k, !isVisited[nr][nc][nb] else { continue }
48+
queue.append(Point(r: nr, c: nc, moveCount: currentPoint.moveCount+1, breakCount: nb))
49+
isVisited[nr][nc][nb] = true
50+
} else {
51+
queue.append(Point(r: nr, c: nc, moveCount: currentPoint.moveCount+1, breakCount: currentPoint.breakCount))
52+
isVisited[nr][nc][currentPoint.breakCount] = true
53+
}
54+
}
55+
index += 1
56+
}
57+
}
58+
59+
bfs()
60+
61+
print(answer == Int.max ? -1 : answer + 1)

0 commit comments

Comments
 (0)