프로그래머스/알고리즘 고득점 Kit

[프로그래머스] [스택/큐] Lv.2 /다리를 지나는 트럭 (파이썬/Python)

junslee 2025. 4. 9. 17:21

1. 문제 설명

2. 코드 

from collections import deque

def solution(priorities, location):
    queue = deque([(p, idx) for idx, p in enumerate(priorities)])
    count = 0
    
    while queue:
        current = queue.popleft()
        if any(x[0] > current[0] for x in queue):
            queue.append(current)
        else:
            count += 1
            if current[1] == location:
                return count

3. 풀이 과정

다리 상태를 나타내는 리스트를 bridge에 0으로 bridge_length만큼 초기화 시킨다.

총 경과 시간을 나타낼 time을 0으로 초기화한다.

현재 다리 위에 있는 트럭들의 총 무게를 bridge_weight에 0으로 초기화한다.

대기 트럭이 있거나 다리 위에 트럭이 아직 있는 동안 반복하는 while문을 작성한다.

매 스텝마다 시간 1초 증가한다.

bridge 리스트의 맨 앞 요소를 제거하고 그 무게만큼 bridge_weight가 감소한다.

대기 중인 트럭이 있는 경우

bridge_weight값과 truck_weights[0]값의 합이 weight보다 작거나 같으면

pop(0)으로 대기열에서 다음 truck을 꺼내고 다리 리스트의 맨 뒤에 append()로 추가한다.

bridge_weight에 truck의 무게를 더한다.

weight보다 작거나 같으면 0을 bridge를 추가한다.

while문을 빠져나오면 time을 반환한다.

4. 추천 코드

from collections import deque

def solution(bridge_length, weight, truck_weights):
    bridge = deque(0 for _ in range(bridge_length))
    total_weight = 0
    step = 0
    truck_weights.reverse()

    while truck_weights:
        total_weight -= bridge.popleft()
        if total_weight + truck_weights[-1] > weight:
            bridge.append(0)
        else:
            truck = truck_weights.pop()
            bridge.append(truck)
            total_weight += truck
        step += 1

    step += bridge_length

    return step

5. 추천 코드의 풀이 과정

collections 모듈에서 deque를 가져옵니다.

다리 상태를 나타내는 덱(deque)을 bridge에 0으로 bridge_length만큼 초기화시킵니다. (덱은 양쪽 끝에서 데이터를 추가하거나 제거하는 데 효율적입니다.)

현재 다리 위에 있는 트럭들의 총 무게를 total_weight에 0으로 초기화합니다.

총 경과 시간을 나타낼 step을 0으로 초기화합니다.

truck_weights.reverse()를 호출하여 대기 트럭 리스트를 뒤집습니다. 이는 리스트의 맨 뒤에서 트럭을 효율적으로 꺼내기 위함입니다 (pop() 사용 목적).

대기 트럭(truck_weights)이 있는 동안 반복하는 while문을 작성합니다. (주의: 이 루프는 마지막 트럭이 다리에 올라가는 시점까지만 실행됩니다.)

 매 반복 시작 시, bridge.popleft()를 사용하여 다리(덱)의 맨 앞에서 요소를 제거하고, 제거된 요소의 무게(트럭 무게 또는 0)만큼 total_weight를 감소시킵니다. 이는 트럭이 다리를 한 칸 전진하거나 완전히 건너는 것을 의미합니다.

현재 다리 위 총 무게(total_weight)와 다음 대기 트럭(뒤집힌 리스트의 마지막 요소, truck_weights[-1])의 무게 합이 다리 허용 무게(weight)보다 큰지 확인합니다.

 새 트럭을 올릴 수 없으므로, bridge.append(0)을 사용하여 다리(덱)의 맨 뒤에 0(빈 공간)을 추가합니다.

truck_weights.pop()을 사용하여 뒤집힌 대기열의 마지막 트럭(원래는 가장 먼저 기다리던 트럭)을 꺼내 truck 변수에 저장합니다.

bridge.append(truck)을 사용하여 이 truck을 다리(덱)의 맨 뒤에 추가합니다.

total_weight += truck을 사용하여 현재 다리 위 총 무게를 업데이트합니다.

각 반복의 끝에서 step += 1을 실행하여 경과 시간을 1 증가시킵니다.

 while문을 빠져나오면, 이는 마지막 트럭이 이제 막 다리에 올라갔음을 의미합니다. 이 마지막 트럭이 다리를 완전히 건너기까지는 다리 길이(bridge_length)만큼의 시간이 더 필요하므로, step += bridge_length를 실행하여 최종 시간에 이 값을 더해줍니다.

 최종 계산된 시간 step을 반환합니다.