코딩 테스트/자료구조

[프로그래머스] 42583 다리를 지나는 트럭(Lv2) - 큐

토자맨 2024. 6. 30. 23:22

문제

입출력 예시

코드

도저히 내 머리로는 못풀겠어서 다른 사람의 코드를 보고 이해하는 식으로 진행했다.

우선 다리를 Queue로 선언하고 아래 세 조건에 따라 트럭을 이동하도록 했다.

  1. 큐(다리)가 비어있는 경우
    큐(다리)에 트럭을 올리고 올리는 시간(time+=1), 현재 다리 위 트럭의 무게(bridge_weight)를 업데이트 한다.
  2. 큐(다리)가 가득 차지 않은 경우
    • 대기 중인 트럭을 큐(다리)에 올릴 수 있는 경우
      (현재 다리 위 트럭의 무게(bridge_weight) + 대기중인 다음 트럭의 무게(truck_weights[i])가 최대 수용 가능한 무게(weight)보다 큰 경우(bridge_weight+truck_weights[i] > weight))
      • 대기중인 트럭을 올릴 수 없다.
      • 현재 트럭을 1초 이동해야 한다.
        • time += 1
      • 다음 대기 중인 트럭을 올릴 수 없으니 임시로 0을 추가해서 q.size()를 +1 해준다.
        • q.add(0)
    • 대기 중인 트럭을 큐(다리)에 올릴 수 없는 경우
      (현재 다리 위 트럭의 무게(bridge_weight) + 대기중인 다음 트럭의 무게(truck_weights[i])가 최대 수용 가능한 무게(weight)보다 작은 경우(bridge_weight+truck_weights[i] <= weight))
      • 현재 다리 위에 있는 트럭을 1초 이동시키고 다음 트럭이 진입할 수 없으므로 0을 큐에 삽입한다.
  3. 큐(다리)가 가득 찬 경우 -> 맨 앞 트럭이 다리 끝에 도달한 경우
    • 다리의 끝에 도달한 트럭을 큐와 현재 다리 위 트럭의 무게(bridge_weight)에서 뺴준다.
    import java.util.*;

    class Solution {
        public int solution(int bridge_length, int weight, int[] truck_weights) {
            Queue<Integer> q = new LinkedList<>();

            int bridge_weight = 0;
            int time = 0;

            for (int i = 0; i < truck_weights.length; i++) {

                while(true) {
                    // 큐가 빈 경우
                    if (q.isEmpty()) {
                        // 큐(다리)에 트럭 올리기 (올리는 시간 1)
                        q.add(truck_weights[i]);
                        bridge_weight += truck_weights[i];
                        time += 1;
                        break; // 트럭을 올렸으니 다음 트럭으로 이동
                    }

                    // 큐(다리)가 가득차지 않은 경우
                    else if (q.size() == bridge_length) {
                        bridge_weight -= q.poll();

                    }

                    // 큐(다리)가 가득 찬 경우
                    // 맨 앞 트럭이 다 왔다는 뜻 -> 큐(다리)에서 맨 앞에 있는 트럭 뺴기
                    else { // q.size() == bridge_length
                        // 다음 트럭을 올릴 수 없는 경우 -> 기존의 트럭을 1칸(1초) 이동
                        if (bridge_weight+truck_weights[i] > weight) {
                            q.add(0);
                            time += 1;
                        }

                        // 다음 트럭을 올릴 수 있는 경우 -> 새로운 트럭 올리기(1초)
                        else {
                            q.add(truck_weights[i]);
                            bridge_weight += truck_weights[i];
                            time += 1;
                            break; // 트럭을 올렸으니 다음 트럭으로 이동
                        }

                    }
                }
            }
            return time + bridge_length; 
        }
    }