ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 14503 로봇 청소기
    Algorithm/BOJ 2021. 3. 19. 14:04
    728x90

    출처: 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

    댓글

Designed by Tistory.