-
백준 14503 로봇 청소기Algorithm/BOJ 2021. 3. 19. 14:04728x90
출처: www.acmicpc.net/problem/14503
분류: 시뮬레이션
접근방식
현재 방향을 생각하면서 청소기를 돌려주면 되는 문제였습니다.
저는 현재 로봇 청소기의 위치와 현재 방향을 전역변수로 두고 둘을 조작해주면서 계산했습니다.
방향을 enum 타입으로 정의했고
청소기는 계속 왼쪽 방향으로 회전하기 때문에 각 방향에서 왼쪽으로 회전하는 함수를 만들었습니다.enum Direction: Int { case up = 0, right, down , left mutating func turnLeft() { switch self { case .up: self = .left case .left: self = .down case .down: self = .right case .right: self = .up } } }
현재 방향과 위치에서 앞 뒤도 계속 사용되기 때문에 computed property로 만들어줬습니다.
var front: Point { switch currentDir { case .up: return (currentPoint.r-1, currentPoint.c) case .left: return (currentPoint.r, currentPoint.c-1) case .down: return (currentPoint.r+1, currentPoint.c) case .right: return (currentPoint.r, currentPoint.c+1) } } var back: Point { switch currentDir { case .up: return (currentPoint.r+1, currentPoint.c) case .left: return (currentPoint.r, currentPoint.c+1) case .down: return (currentPoint.r-1, currentPoint.c) case .right: return (currentPoint.r, currentPoint.c-1) } }
그리고 네 방향에 청소할 곳이 있는지 확인하는 함수를 하나 만들었는데요,
가능하다면 해당 위치로 바꿔주고 true를 아니라면 false를 리턴해주도록 했습니다.func availableNextClean() -> Bool { for _ in 0..<4 { currentDir.turnLeft() if map[front.r][front.c] == 0 { currentPoint = front return true } } return false }
마지막으로 이를 종합해주면 됩니다.
현재 위치가 벽일 때까지 while문을 돌렸는데요,
현재 위치를 청소해야하면 하고 (청소하고나면 2로 바꿔줬습니다.)
아니라면 다음 위치로 이동이 가능한지 확인하고
못한다면 빽을 해줬습니다. (빽을 한 위치가 벽이라면 다음 턴에서 종료되겠죠 :))func runCleaner() { while map[currentPoint.r][currentPoint.c] != 1 { if map[currentPoint.r][currentPoint.c] == 0 { map[currentPoint.r][currentPoint.c] = 2 cleanCount += 1 } if !availableNextClean() { currentPoint = back } } }
해결방법
// 14503 로봇청소기 let nm = readLine()!.split(separator: " ").map { Int(String($0))! } let rcd = readLine()!.split(separator: " ").map { Int(String($0))! } var map = [[Int]]() for _ in 0..<nm[0] { map.append(readLine()!.split(separator: " ").map { Int(String($0))! }) } typealias Point = (r: Int, c: Int) enum Direction: Int { case up = 0, right, down , left mutating func turnLeft() { switch self { case .up: self = .left case .left: self = .down case .down: self = .right case .right: self = .up } } } var currentDir = Direction(rawValue: rcd[2])! var currentPoint = Point(rcd[0], rcd[1]) var front: Point { switch currentDir { case .up: return (currentPoint.r-1, currentPoint.c) case .left: return (currentPoint.r, currentPoint.c-1) case .down: return (currentPoint.r+1, currentPoint.c) case .right: return (currentPoint.r, currentPoint.c+1) } } var back: Point { switch currentDir { case .up: return (currentPoint.r+1, currentPoint.c) case .left: return (currentPoint.r, currentPoint.c+1) case .down: return (currentPoint.r-1, currentPoint.c) case .right: return (currentPoint.r, currentPoint.c-1) } } var cleanCount = 0 func availableNextClean() -> Bool { for _ in 0..<4 { currentDir.turnLeft() if map[front.r][front.c] == 0 { currentPoint = front return true } } return false } func runCleaner() { while map[currentPoint.r][currentPoint.c] != 1 { if map[currentPoint.r][currentPoint.c] == 0 { map[currentPoint.r][currentPoint.c] = 2 cleanCount += 1 } if !availableNextClean() { currentPoint = back } } } runCleaner() print(cleanCount)
배운점
구현이 쬐끔 오래걸렸고 back 구현에서 위랑 아래를 거꾸로 써서 2번 예제를 한 40 몇번까지 디버깅했던 것 같다... 후우....ㅂㄷㅂㄷ
그리고 문제에서 서쪽이 1인데 동쪽을 1로 하고 돌려서 틀려서 또 애를 먹었따..
실수 그만!!!
'Algorithm > BOJ' 카테고리의 다른 글
백준 5639 이진 검색 트리 (0) 2021.03.26 백준 1068 트리 (0) 2021.03.25 백준 17135 캐슬디펜스 (0) 2021.03.18 백준 17142 연구소 3 (0) 2021.03.17 백준 10819 차이를 최대로 (0) 2021.03.16