2021 하반기 진짜마지막 데브매칭 코딩 테스트 2번

하루히즘·2021년 12월 5일
0
post-custom-banner

설명

[문제 비공개]

풀이

import java.util.*;


class Solution {

    public int solution(int n, String[] recipes, String[] orders) {
        // 레시피 시간 등록.
        Map<String, Integer> recipeTime = new HashMap<>();
        for(String recipe: recipes) {
            String[] args = recipe.split(" ");
            recipeTime.put(args[0], Integer.parseInt(args[1]));
        }

        int handledOrder = 0;
        int[] furnaces = new int[n]; // 0: idling. else: working.
        int tick = 0;
        int answer = 0;
        while(handledOrder < orders.length) {
            tick++;
            // 화로에서 요리중인 요리 진행.
            for(int i=0;i<furnaces.length;i++) {
                furnaces[i] = Math.max(0, furnaces[i] - 1);
            }

            // 주문받은 요리가 있더라도 현재 화로가 작업중이라 바로 요리를
            // 할 수 없는 경우 그 주문을 가리켜야 함.

            // 마지막 요리라면 직접 처리.
            if(handledOrder == orders.length - 1) {
                // System.out.printf("Order %s is last order. taking personally.%n", orders[handledOrder]);
                int requiredTime = recipeTime.get(
                    orders[handledOrder].split(" ")[0]);

                // 가장 빨리 끝나는 화로를 탐색.
                int min = furnaces[0];
                int furnaceIndex = 0;
                for(int i=0;i<furnaces.length;i++) {
                    if(furnaces[i] < min) {
                        min = furnaces[i];
                        furnaceIndex = i;
                    }
                }

                // 화로의 남은 시간과 오더가 들어오는 시간 사이의 간격을 고려해야 함.
                // 화로의 남은 시간, 현재 tick, 요리 시간을 합하여 계산.
                answer = Math.max(
                            tick + furnaces[furnaceIndex], // 현재 시간 + 화로 남은 시간
                            Integer.parseInt(orders[handledOrder].split(" ")[1])) // 요리 접수 시간
                  + requiredTime;
                break;
            }

            // 마지막 요리가 아닌 경우 비어있는 화로가 있다면 요리를 진행.
            // 밀린 요리가 여러 개 있을 수 있으므로 다 넣어줘야함.
            for(int i=0;i<furnaces.length;i++) {
                if(furnaces[i] == 0) {               
                    String targetOrder = orders[handledOrder];
                    if(Integer.parseInt(targetOrder.split(" ")[1]) > tick) {
                        break; // 주문받지 않은 요리는 화로에 넣을 수 없음.
                    }
                    furnaces[i] = recipeTime.get(targetOrder.split(" ")[0]);
                    handledOrder++;
                    // System.out.printf("Handled order %s at tick %s%n", targetOrder, tick);
                }
            }
        }

        return answer;
    }
}

여기서부터 조금 헷갈려서 주석을 쓰면서 풀기 시작했던 것 같다. 생각했던 대로 안 풀려서 조금 당황했는데 놓쳤던 부분은 모든 화로가 작동중인데 주문이 여러 개 들어왔다면 화로의 요리가 끝나는 대로 주문들을 즉시 처리해야 한다는 점이다.

당연한 요구사항이고 그래서 마지막 반복문에서 화로를 확인하면서 주문을 처리하는 로직을 볼 수 있는데 원래는 if 문이 끝나고 break 를 통해 반복문을 탈출했었다. 아마 처음 생각에는 다음처럼 생각했던 것 같다.

  • 빈 화로를 탐색.
  • 빈 화로에 handledOrder가 가리키는 현재 대기중인 주문을 처리.
  • 빈 화로를 찾았고 주문을 처리했으니 break.

하지만 빈 화로가 하나라는 보장이 없기 때문에 한 화로가 주문을 처리했더라도 다른 화로가 비어있는 경우 밀린 주문을 계속 처리해야 했다. 그래서 break 를 제거하고 반복문을 수정한 결과 정상적으로 통과할 수 있었다.

profile
YUKI.N > READY?
post-custom-banner

0개의 댓글