Skip to content

Commit 6145b93

Browse files
committed
[Gold III] Title: 벽 부수고 이동하기 2, Time: 892 ms, Memory: 696872 KB -BaekjoonHub
1 parent a433d7f commit 6145b93

2 files changed

Lines changed: 48 additions & 54 deletions

File tree

백준/Gold/14442. 벽 부수고 이동하기 2/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
### 성능 요약
66

7-
메모리: 956036 KB, 시간: 1904 ms
7+
메모리: 696872 KB, 시간: 892 ms
88

99
### 분류
1010

1111
그래프 이론, 그래프 탐색, 너비 우선 탐색, 격자 그래프
1212

1313
### 제출 일자
1414

15-
2025년 8월 28일 14:48:17
15+
2025년 8월 28일 14:59:04
1616

1717
### 문제 설명
1818

Lines changed: 46 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,55 @@
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
1+
//14442번 벽 부수고 이동하기2
122

13-
for _ in 0..<n {
14-
let line = readLine()!.map { Int(String($0))! }
15-
map.append(line)
16-
}
3+
import Foundation
4+
5+
func bfs() -> Int {
6+
let dx = [1, -1, 0, 0]
7+
let dy = [0, 0, 1, -1]
8+
9+
var visit = [[Int]](repeating: [Int](repeating: k+1, count: m), count: n)
10+
visit[0][0] = 0
11+
12+
var queue = [(0, 0, 1)]
13+
var idx = 0
14+
15+
while queue.count > idx {
16+
let (x, y, dist) = queue[idx]
17+
idx += 1
18+
19+
if x == n - 1 && y == m - 1 { return dist }
1720

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-
}
4021
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
22+
let nx = x + dx[i]
23+
let ny = y + dy[i]
24+
25+
guard (0..<n) ~= nx && (0..<m) ~= ny else { continue }
26+
27+
// 다음칸이 벽인지 + 현재까지 부순 벽의 갯수
28+
// 현재까지 부순 벽의 갯수가 0개이고, 다음 칸이 벽이여서 1이라고 하자.
29+
// 부술 벽의 visit에는 1이 할당될 것이다.
30+
// 이것이 쭉 쌓이다, 다음 상황을 고려해보자.
31+
// 현재까지 부순 벽의 갯수가 10개이고, 다음 칸이 벽이여서 1이라고 하자.
32+
// 부술 벽의 visit에는 11이 할당될 것 이다.
33+
// 다음에 이 벽이 탐색 대상으로 고려될 때, 이보다 작으면 탐색한다.
34+
let brokenWallCount = graph[nx][ny] + visit[x][y]
35+
36+
if brokenWallCount < visit[nx][ny] && brokenWallCount <= k {
37+
visit[nx][ny] = brokenWallCount
38+
queue.append((nx, ny, dist + 1))
5339
}
5440
}
55-
index += 1
5641
}
42+
43+
return -1
5744
}
5845

59-
bfs()
46+
let t = readLine()!.split { $0 == " " }.map { Int($0)! }
47+
let (n, m, k) = (t[0], t[1], t[2])
48+
49+
var graph = [[Int]]()
50+
for _ in 0..<n {
51+
let line = Array(readLine()!).map { Int(String($0))! }
52+
graph.append(line)
53+
}
6054

61-
print(answer == Int.max ? -1 : answer + 1)
55+
print(bfs())

0 commit comments

Comments
 (0)