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