Problem Solving/Programmers

【프로그래머스】 스택/큐 - 다리를 지나는 트럭 (Kotlin)

까망사과 2022. 7. 5. 22:30

문제 설명

트럭 여러 대가 강을 가로지르는 일차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 다리에는 트럭이 최대 bridge_length대 올라갈 수 있으며, 다리는 weight 이하까지의 무게를 견딜 수 있습니다. 단, 다리에 완전히 오르지 않은 트럭의 무게는 무시합니다.

 

예를 들어, 트럭 2대가 올라갈 수 있고 무게를 10kg까지 견디는 다리가 있습니다. 무게가 [7, 4, 5, 6]kg인 트럭이 순서대로 최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다.

경과 시간 다리를 지난 트럭 다리를 건너는 트럭 대기 트럭
0 [] [] [7, 4, 5, 6]
1~2 [] [7] [4, 5, 6]
3 [7] [4] [5, 6]
4 [7] [4, 5] [6]
5 [7, 4] [5] [6]
6~7 [7, 4, 5] [6] []
8 [7, 4, 5, 6] [] []

 

따라서, 모든 트럭이 다리를 지나려면 최소 8초가 걸립니다.

 

solution 함수의 매개변수로 다리에 올라갈 수 있는 트럭 수 bridge_length, 다리가 견딜 수 있는 무게 weight, 트럭 별 무게 truck_weights가 주어집니다. 이때 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요.

 

제한 사항

  • bridge_length는 1 이상 10,000 이하입니다.
  • weight는 1 이상 10,000 이하입니다.
  • truck_weights의 길이는 1 이상 10,000 이하입니다.
  • 모든 트럭의 무게는 1 이상 weight 이하입니다.

 

입출력 예

bridge_length weight truck_weights return
2 10 [7, 4, 5, 6] 8
100 100 [10] 101
100 100 [10, 10, 10, 10, 10, 10, 10, 10, 10, 10] 110

 


풀이

큐를 2개 준비한다. 하나는 대기 중인 트럭들을 나타내는 waiting이고 다른 하나는 다리를 나타내는 bridge이다. bridge는 길이가 bridge_length이고 각 위치가 비어있다는 의미로 0을 저장한다. waiting에는 truck_weights에 있는 각 트럭의 무게를 순서대로 추가한다.

 

가변형 변수도 2개 준비한다. 다리에 올라와 있는 트럭의 무게의 합을 나타내는 totalWeight, 트럭들이 다리를 지나면서 경과하는 시간을 나타내는 time이다. 단계마다 time은 1씩 증가시키고 트럭의 출입에 따라 totalWeight의 값을 바꿀 것이다.

 

while 문으로 아래 작업을 반복한다. 트럭이 모두 지나갈 때까지 반복할 것이므로 bridge.isNotEmpty()를 조건문으로 놓는다.

  1. 시간이 1초 지났으므로 time을 1 증가시킨다.
  2. 다리 끝에 있는 트럭이 나가야 하므로 totalWeightbridge의 맨 앞 요소(트럭의 무게)만큼 감소시킨다.
    만약 bridge의 맨 앞에 트럭이 없다면 요소가 0이므로 변화가 없을 것이다.
  3. 지나가야 하는 트럭이 남아 있을 경우 waiting의 맨 앞에 있는 트럭의 무게를 nextWeight라 하자.
    weightSum + nextWeight가 무게 한도 이하라면 weightSumnextWeight만큼 증가시키고 nextWeightbridge에 추가한다. 그렇지 않으면 트럭이 다리에 들어가지 못하는 것이므로 bridge에 0을 추가한다.

 

대기열에 트럭이 남아있는 동안 bridge의 맨 앞 요소가 제거되고 뒤에 요소가 추가되는 과정을 반복하므로 크기가 유지된다. 대기열이 비게 되면 3을 건너뛰기 때문에 bridge에서 요소가 제거되기만 하고 추가되지는 않는다. 이렇게 하면 마지막 트럭이 다리를 지나갈 때까지 time이 증가되어 시간을 제대로 잴 수 있다.

 

코드

import java.util.LinkedList

fun solution(bridgeLength: Int, weight: Int, truckWeights: IntArray): Int {
    var answer = 0
    val bridge = LinkedList(List(bridgeLength) { 0 })
    val waiting = LinkedList(truckWeights.toList())
    var totalWeight = 0

    while (bridge.isNotEmpty()) {
        answer++
        totalWeight -= bridge.poll()

        if (waiting.isNotEmpty()) {
            val nextWeight = waiting.peek()

            if (totalWeight + nextWeight <= weight) {
                totalWeight += nextWeight
                bridge.add(waiting.poll())
            } else {
                bridge.add(0)
            }
        }
    }
    
    return answer
}