내가 내는 코딩테스트 - 벽 짚고 가기
문제
배열이 주워질 때 0.0 왼쪽 위 부터 시작해서 오른쪽 아래까지 벽만 짚고 가고자 한다.
한 벽면을 갈 때 1만큼의 시간이 소비된다.
이 때 공간에서는 장애물이 존재한다. 장애물의 크기는 1X1이다.
장애물이 없는 곳은 0 장애물이 있는 곳은 1 로
[[Int]]
형태로 주워진다.이 때 왼쪽 위에서 오른쪽 아래까지 손에 벽을 안 띄고 가고자 한다.
이 때 걸리는 최소시간을 구해라. 만약 오른쪽 아래까지 도달하지 못한다면 -1을 반환할 것
코드
func solution(_ road: [[Int]]) -> Int {
let Y = road.count
let X = road[0].count
let temp = [[Bool]](repeating: [Bool](repeating: false, count: X), count: Y)
var answer = Int.max
var visited = [temp, temp, temp, temp]
let dir = ["상", "하", "좌", "우"]
func dfs(_ y: Int, _ x: Int, _ d: Int, _ count: Int) {
if visited[d][y][x] { return }
// 종료
if y == Y - 1 && x == X - 1 && (d == 3 || d == 1) {
answer = min(answer, count)
return
}
visited[d][y][x] = true
if d == 0 {
if x + 1 < X {
if road[y][x + 1] == 0 {
if y - 1 >= 0, road[y - 1][x + 1] == 0 {
dfs(y - 1, x + 1, 2, count + 1)
} else {
dfs(y, x + 1, d, count + 1)
}
} else {
dfs(y, x, 3, count + 1)
}
} else {
dfs(y, x, 3, count + 1)
}
if x - 1 >= 0 {
if road[y][x - 1] == 0 {
if y - 1 >= 0, road[y - 1][x - 1] == 0 {
dfs(y - 1, x - 1, 3, count + 1)
} else {
dfs(y, x - 1, d, count + 1)
}
} else {
dfs(y, x, 2, count + 1)
}
} else {
dfs(y, x, 2, count + 1)
}
}
if d == 1 {
if x + 1 < X {
if road[y][x + 1] == 0 {
if y + 1 < Y, road[y + 1][x + 1] == 0 {
dfs(y + 1, x + 1, 2, count + 1)
} else {
dfs(y, x + 1, d, count + 1)
}
} else {
dfs(y, x, 3, count + 1)
}
} else {
dfs(y, x, 3, count + 1)
}
if x - 1 >= 0 {
if road[y][x - 1] == 0 {
if y + 1 < Y, road[y + 1][x - 1] == 0 {
dfs(y + 1, x - 1, 3, count + 1)
} else {
dfs(y, x - 1, d, count + 1)
}
} else {
dfs(y, x, 2, count + 1)
}
} else {
dfs(y, x, 2, count + 1)
}
}
if d == 2 {
if y + 1 < Y {
if road[y + 1][x] == 0 {
if x - 1 >= 0, road[y + 1][x - 1] == 0 {
dfs(y + 1, x - 1, 0, count + 1)
} else {
dfs(y + 1, x, d, count + 1)
}
} else {
dfs(y, x, 1, count + 1)
}
} else {
dfs(y, x, 1, count + 1)
}
if y - 1 >= 0 {
if road[y - 1][x] == 0 {
if x - 1 >= 0, road[y - 1][x - 1] == 0 {
dfs(y - 1, x - 1, 1, count + 1)
} else {
dfs(y - 1, x, d, count + 1)
}
} else {
dfs(y, x, 0, count + 1)
}
} else {
dfs(y, x, 0, count + 1)
}
}
if d == 3 {
if y + 1 < Y {
if road[y + 1][x] == 0 {
if x + 1 < X, road[y + 1][x + 1] == 0 {
dfs(y + 1, x + 1, 0, count + 1)
} else {
dfs(y + 1, x, d, count + 1)
}
} else {
dfs(y, x, 1, count + 1)
}
} else {
dfs(y, x, 1, count + 1)
}
if y - 1 >= 0 {
if road[y - 1][x] == 0 {
if x + 1 < X, road[y - 1][x + 1] == 0 {
dfs(y - 1, x + 1, 1, count + 1)
} else {
dfs(y - 1, x, d, count + 1)
}
} else {
dfs(y, x, 0, count + 1)
}
} else {
dfs(y, x, 0, count + 1)
}
}
}
// 0: 상
// 1: 하
// 2: 좌
// 3: 우
dfs(0, 0, 0, 1)
visited = [temp, temp, temp, temp]
dfs(0, 0, 2, 1)
return answer == Int.max ? -1 : answer
}
let arr = [
[0, 0, 1, 0],
[0, 0, 1, 0],
[0, 0, 1, 0],
[0, 0, 0, 0]
]
print(solution(arr))
해결 방법
3차원 배열을 써서 지금 내가 [상 하 좌 우] 중에 어느 벽을 짚고 있는지 알아야하는게 KeyPoint
문제 출저
벽짚고 계단 올라오다가 문제가 떠올라서 문제도 만들고 풀어봤음.
출제 과정 중 생각
Dynamic Programing으로도 풀 수 있지 않을까 싶었는데, 2방향으로 무조권 시작하고 갔던 방향으로 다시 돌아가지 않으니깐 DP는 의미 없는 듯하다.
문제의 KeyPoint는 회전이다. 장애물이 튀어나왔을 때 벽 짚고 회전하는 것을 잘 구현할 수 있느냐가 포인트(?)