Swift) 백준 20055번 컨베이어 벨트위의 로봇 - G5

https://www.acmicpc.net/problem/20055

 

20055번: 컨베이어 벨트 위의 로봇

길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부

www.acmicpc.net

고민한 부분

컨베이어 벨트를 회전시키는 부분에서 고민이 좀 있었다. 처음에는 2차원 배열로 요소들을 한칸씩 이동 시키는 방식을 생각했지만, 컨베이어 벨트를 잘라서 펼치면 결국엔 한줄이 되고 양 끝이 서로 이어져 있으므로

 

기존 컨베이어 벨트 배열이 1 2 3 4 5 6 이면 removelast와 insert로 마지막 요소를 배열의 첫번째에 넣어주면 

2 3 4 5 6 1 이렇게 한칸씩 회전을 시킬 수 있다. 

swift에서 배열을 이용하여 시간복잡도는 O(n)이였지만, 디큐를 이용한다면 시간복잡도를 O(1)로 줄일수 있다. 하지만 시뮬레이션이라 제한도 널럴해서 그냥 구현함.

 

import Foundation

struct Blank {
    var life: Int
    var hasRobot: Bool
}

let nk = readLine()!.split(separator: " ").map { Int($0)! }
let n = nk[0]
let k = nk[1]
var convainer: [Blank] = []
convainer = readLine()!.split(separator: " ").map { Int($0)! }.map{ .init(life: $0, hasRobot: false)}
var answer = 0
var zeroBlankCount = 0

func lotateConvainer() {
    convainer.insert(convainer.removeLast(), at: 0)
}

func countZeroBlank() {
    var count = 0
    convainer.forEach { blank in
        if blank.life == 0 {
            count += 1
        }
    }
    zeroBlankCount = count
}

while zeroBlankCount < k {
    answer += 1
    lotateConvainer()
    if convainer[n-1].hasRobot {
        convainer[n-1].hasRobot = false
    }
    for i in stride(from: n-2, through: 0, by: -1) {
        if convainer[i].hasRobot && convainer[i+1].life >= 1 && !convainer[i+1].hasRobot {
            convainer[i+1].life -= 1
            convainer[i].hasRobot = false
            if i == n-2 {
                continue
            }
            convainer[i+1].hasRobot = true
        }
    }
    if convainer[0].life >= 1 && !convainer[0].hasRobot {
        convainer[0].hasRobot = true
        convainer[0].life -= 1
    }
    countZeroBlank()
}

print(answer)