알고리즘 단련장/소프티어

[소프티어] 회의실 예약 레벨2 자바 풀이 (21년 재직자 대회 예선)

dcho 2024. 10. 31. 16:54
SMALL

https://softeer.ai/practice/6266

 

Softeer - 현대자동차그룹 SW인재확보플랫폼

 

softeer.ai

 

 

꽤 오랜시간 풀었던 문제였다. 너무 헷갈려서 엄두가 잘 나지 않았다.

회의실 클래스를 만들었다.
해당 속성으로는 아래와 같다.

  • 회의실 이름
  • 예약 현황 list[18] (9-18 저장용 앞에 인덱스는 많지 않으니 버리는 전략)

회의실 클래스를 저장하는 리스트에 각각 담는다.

 

문제에 맞게 저장하고 핵심은 다음과 같다. 

  • 회의실을 저장해주는 리스트 반복을 한다.
    • 각 회의실 마다 가용슬롯을 String 리스트 선언
    • 예약 현황에 저장해둔 list[18]을 9-18 만큼 반복
    • 회의실 예약이 false 이고 start 시점이 잡혀 있지 않다면 start 시점 저장
    • 회의실 예약이 true 이고 start 시점이 잡혀 있다면 해당 영역 만큼 String.format에 맞춰 가용슬롯에 저장하고 start 시점 초기화
    • 마지막 인덱스는 따로 처리 (start 시점이 초기화 안되어있다면 가용슬롯에 저장)

 

정답 코드

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class Main {
    private static final int TIME = 18;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        List<Room> rooms = new ArrayList<>();

        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        // 회의실 이름 입력 받기
        for (int i = 0; i < n; i++) {
            String name = br.readLine();
            rooms.add(new Room(name));
        }

        // 예약 시간 저장
        for (int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            String r = st.nextToken();
            int s = Integer.parseInt(st.nextToken());
            int t = Integer.parseInt(st.nextToken());

            for (Room room : rooms) {
                // 회의실 이름을 찾기
                if (room.name.equals(r)) {
                    // 회의실 시간 저장
                    for (int j = s; j < t; j++) {
                        room.reservation[j] = true;
                    }
                }
            }
        }

        // 회의실 이름 오름차순 정렬
        rooms.sort((r1, r2) -> r1.name.compareTo(r2.name));



        for (int roomIndex = 0; roomIndex < rooms.size(); roomIndex++) {
            Room room = rooms.get(roomIndex);
            List<String> availableSlots = new ArrayList<>();
            int availableStart = -1;

            for (int i = 9; i < 18; i++) {
                // 해당 시간에 회의실 예약이 없을때
                if (!room.reservation[i]) {
                    if (availableStart == -1) {
                        availableStart = i;
                    }
                }
                else {
                    // 예약된 경우, 이전에 가용 시간대가 있었다면 해당 구간을 저장
                    if (availableStart != -1) {
                        availableSlots.add(formatSlot(availableStart, i));
                        availableStart = -1; // 가용 시간대 종료
                    }
                }
            }
            // 마지막 시간대까지 가용 구간이 이어진 경우
            if (availableStart != -1) {
                availableSlots.add(formatSlot(availableStart, 18));
            }

            bw.write("Room " + room.name + ":\n");
            if (availableSlots.isEmpty()) {
                bw.write("Not available\n");
            } else {
                bw.write(availableSlots.size() + " available:\n");
                for (String slot : availableSlots) {
                    bw.write(slot + "\n");
                }
            }
            if (roomIndex != rooms.size() - 1) bw.write("-----\n");

        }


        bw.flush();
        bw.close();
    }

    private static String formatSlot(int start, int end) {
        return String.format("%02d-%02d", start, end);
    }

    static class Room {
        String name;
        boolean[] reservation = new boolean[TIME];

        public Room(String name) {
            this.name = name;
        }
    }
}

 

굉장히 시간이 걸린 문제이다. 앞으로 다 피고 살이 되리라..