[Softeer] Java - level2 문제풀이(회의실 예약)

2023. 2. 8. 21:51·개발자 세릴리/코딩테스트
728x90
반응형

 

softeer 회의실 예약(Java)

[문제]

회사에는 N개의 회의실이 있다. 수많은 팀이 모여 토론하고 업무를 처리하기 위해서는 회의실이 필수적이다.

 

내부망에 아주 간단한 회의실 예약 시스템이 있지만 편의성이 매우 떨어진다. 단순히 예약된 회의의 목록만 표시되기 때문에, 방 별로 비어 있는 시간이 언제인지를 확인하기가 힘든 것이다. 당신은 이를 직접 해결해 보기로 마음 먹었다.

 

회의실 이용 규칙은 다음과 같다:

 

- 회의실은 9시부터 18시까지만 사용 가능하다. 모든 회의의 시간은 이 안에 완전히 포함되어야 한다.

- 회의는 정확히 한 회의실을 연속한 일정 시간 동안만 점유한다. 즉 각 회의는 (회의실, 시작 시각, 종료 시각)의 정보로 나타낼 수 있다.

- 회의의 시작과 종료 시각은 시(時, hour) 단위로만 설정 가능하다. 같은 회의실을 사용하는 회의 시간은 서로 겹칠 수 없다. 여기서 겹친다는 것은, 두 회의 모두에 포함되는 시간이 1시간 이상 존재한다는 것을 의미한다. 예를 들어, 10시-12시의 회의와 11시-13시의 회의는 겹치는데, 11시-12시의 시간이 두 회의 모두에 포함되기 때문이다.

- 한 회의가 끝나는 시각에, 같은 회의실에서 다른 회의가 시작하는 것은 허용된다. 이 경우 두 회의가 겹치지 않기 때문이다.

- 길이가 0인 회의, 즉 시작 시각과 종료 시각이 동일한 회의는 예약된 바 없으며, 새롭게 잡을 수도 없다.

 

이미 예약된 M개의 회의에 대한 정보가 주어지면, 회의실별로 비어 있는 시간대를 정리해 출력하는 프로그램을 작성해 보자. 구체적인 형식은 아래를 참고하시오.

 
[제약조건]

1 ≤ N ≤ 50

1 ≤ M ≤ 100

회의실의 이름은 영문 알파벳 소문자로만 이루어져 있으며 길이는 1 이상 10 이하이다.

주어지는 모든 시각은 9 이상 18 이하이다.

회의의 시작 시각은 회의의 종료 시각을 1시간 이상 앞선다.

 
[입력형식]

첫째 줄에 회의실의 수와 예약된 회의의 수를 나타내는 정수 N과 M이 공백을 사이에 두고 주어진다.

이어 N개의 줄에는 각 회의실의 이름이 주어진다.

이어 M개의 줄에는 각 회의가 배정된 회의실의 이름 r과 시작 시각 s, 그리고 종료 시각 t가 공백을 사이에 두고 주어진다.

 
[출력형식]

각 회의실에 대한 정보를 회의실 이름의 오름차순으로 출력한다.

 

각 회의실에 대한 정보는 다음과 같다.

첫째 줄에는 { Room 회의실이름: } (중괄호 제외)을 출력한다.

둘째 줄에는 예약가능 시간을 출력한다.

- 예약 가능한 시간대의 개수를 n이라고 할 때, { n available: } (중괄호 제외)을 출력하고, 뒤따른 n개의 줄에 예약 가능한 시간대를 { 09-18 } (하이픈 한개, 중괄호 제외)형태로 출력해야 한다. 한 자리 수의 경우 앞에 0을 붙여 두 자리 수로 만들어야 함에 유의하라.

- 예약 가능한 시간이 없다면, Not available을 출력한다.

 

각 회의실에 대한 정보 사이에는 ----- (하이픈 다섯 개)로 구분선이 출력되어야 한다.

 

[풀이]

- 회의실 이름은 List<String> 으로 입력 받아서 가장 먼저 정렬을 해두었습니다.(Collection.sort() 이용)

- 회의실 예약은 HashMap 을 이용해서 입력 받았습니다. 이때 HashMap 의 key 는 room 이름이 들어갈 String, value 는 예약 시간이 들어갈 List<Integer> 으로 입력 받았습니다. 미리 오름차순으로 정렬해둔 회의실 이름을 key 값으로 저장하고, 이후 예약 내용을 저장 받았습니다. 

- 예약시간은 String으로 연결 시킨 값을 Integer 형으로 바꿔서 저장했습니다. 시간 순서대로 정렬하는데 이용하기 위해서 입니다.

- 이후 각 room 이름 순서대로 테스트 케이스라고 생각하고 반복문을 썼습니다. 또 가능한 시간을 담을 availableTime 을 선언해서 사용했습니다.

1. 예약이 없는 경우 : 09-18 가능

2. 예약이 한 건 있는 경우 : 예약건 앞만 비거나, 앞 뒤로 비거나, 뒤만 비는 세 가지 경우의 수 가능

3. 예약건이 여러 건인 경우 : 예약건의 시작 시간과 종료 시간을 확인하며 빈 시간을 확인하며 availableTime에 저장해갑니다.

- 마지막 출력은 availableTime 의 size()가 0이면 Not available을, 아니라면 가능한 시간이 짝수로만 시간이 저장되기 때문에 2건씩 출력해 줍니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = br.readLine().split(" ");
        int N = Integer.parseInt(input[0]);
        int M = Integer.parseInt(input[1]);
        List<String> room = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            room.add(br.readLine());
        }
        Collections.sort(room);
        HashMap<String, List<Integer>> reservation = new HashMap<>();
        for (int i = 0; i < N; i++) {
            reservation.put(room.get(i), new ArrayList<>());
        }
        for (int i = 0; i < M; i++) {
            String[] temp = br.readLine().split(" ");
            String tempTime = temp[1] + temp[2];
            reservation.get(temp[0]).add(Integer.parseInt(tempTime));
        }
        int start;
        int end;
        boolean available = true;
        for (int i = 0; i < N; i++) {
            List<Integer> availableTime = new ArrayList<>();
            List<Integer> checkTime = reservation.get(room.get(i));
            Collections.sort(checkTime);
            /*예약이 하나도 들어오지 않은 경우*/
            if (checkTime.size() == 0) {
                availableTime.add(9);
                availableTime.add(18);
            }
            /*예약이 한 건만 들어온 경우*/
            for (int j = 0; j < checkTime.size(); j++) {
                start = checkTime.get(j) / 100;
                end = checkTime.get(j) % 100;
                if (checkTime.size() == 1) {
                    if (start < 9) {
                        available = false;
                    } else if (start > 9) {
                        if (end < 18) {
                            availableTime.add(9);
                            availableTime.add(start);
                            availableTime.add(end);
                            availableTime.add(18);
                        } else {
                            availableTime.add(9);
                            availableTime.add(start);
                        }
                    } else {
                        if (end >= 18) {
                            available = false;
                        } else {
                            availableTime.add(end);
                            availableTime.add(18);
                        }
                    }
                /*예약이 2건 이상 들어온 경우*/
                } else {
                    /*첫 번째 예약 건*/
                    if (j == 0) {
                        if (start < 9) {
                            available = false;
                        } else if (start > 9) {
                            availableTime.add(9);
                            availableTime.add(start);
                            availableTime.add(end);
                        } else {
                            availableTime.add(end);
                        }
                    /*마지막 예약 건*/
                    } else if (j == checkTime.size() - 1) {
                        if (end < 18) {
                            if (availableTime.get(availableTime.size() - 1) > start) {
                                available = false;
                            } else if (availableTime.get(availableTime.size() - 1) < start) {
                                availableTime.add(start);
                                availableTime.add(end);
                                availableTime.add(18);
                            } else {
                                availableTime.remove(availableTime.size() - 1);
                                availableTime.add(end);
                                availableTime.add(18);
                            }
                        } else if (end > 18) {
                            available = false;
                        } else {
                            if (availableTime.get(availableTime.size() - 1) > start) {
                                available = false;
                            } else if (availableTime.get(availableTime.size() - 1) < start) {
                                availableTime.add(start);
                            } else {
                                availableTime.remove(availableTime.size() - 1);
                            }
                        }
                    /*중간 예약 건*/
                    } else {
                        if (availableTime.get(availableTime.size() - 1) > start) {
                            available = false;
                        } else if (availableTime.get(availableTime.size() - 1) < start) {
                            availableTime.add(start);
                            availableTime.add(end);
                        } else {
                            availableTime.remove(availableTime.size() - 1);
                            availableTime.add(end);
                        }
                    }
                }
            }
            System.out.println("Room " + room.get(i) + ":");
            if (!available || availableTime.size() == 0) {
                System.out.println("Not available");
            } else {
                System.out.println(availableTime.size() / 2 + " available:");
                for (int j = 0; j < availableTime.size(); j += 2) {
                    if (availableTime.get(j) < 10) {
                        System.out.print("0" + availableTime.get(j) + "-");
                        System.out.println(availableTime.get(j + 1));
                    } else {
                        System.out.print(availableTime.get(j) + "-");
                        System.out.println(availableTime.get(j + 1));
                    }
                }
            }
            if (i != room.size() - 1) {
                System.out.println("-----");
            }
            available = true;
        }
        br.close();
    }
}

 

문제에서 주어지는 테스트 케이스가 2개 뿐이지만, 소프티어 문제들의 특징은 답안을 제출했을 때 더 많은 테스트 케이스를 실행시켜 정답 판별을 합니다. 그래서 예시 사항 중 회의실 예약이 겹치는 경우와 9-18시를 벗어나는 예약이 있는 경우를 전부 생각하며 작성했더니 코드가 엄청 길어졌습니다ㅠㅠ. 덕분에 한 번만에 정답을 맞출 수 있었지만 아무래도 코드 길이(깔끔함)에 아쉬움이 남습니다.

이틀 동안 문제가 풀리지 않아서 검색을 했을 때 파이썬 코드로 푼 해결법만 확인할 수 있었습니다. 단순히 보기엔 파이썬 코드들은 아주 간단해서 더 아쉬움이 남았지 않나 싶습니다. 파이썬의 자료구조에 대해 잘은 모르지만, 개인적으로 Java 자료구조도 데이터를 다루기에 좀 더 다양해졌으면 하는 바람입니다.

제가 잘 이용할 줄 모르는 것일 수도 있지만.... 스택을 썼을 땐 자료를 출력할 때 아쉽고.... 배열을 쓰면 정렬(sort)할 때 아쉽고....

여러모로 자료구조를 바꿔가며 해결해야하는 부분이 많아서 아직은 너무 어렵습니다ㅠㅠ

 

혹시라도 저처럼 java로 문제를 푸는 분이 계시다면 도움이 되셨으면 좋겠고, 더 좋은 해결법이 있다면 알려주세요! 감사히 배우겠습니다 :)

728x90
반응형

'개발자 세릴리 > 코딩테스트' 카테고리의 다른 글

[Softeer] Java - level2 문제풀이(GBC)  (0) 2023.02.11
[Softeer] Java - level2 문제풀이(전광판)  (0) 2023.02.10
[Softeer] Java - level2 문제풀이(비밀 메뉴)  (0) 2023.02.04
[Softeer] Java - level2 문제풀이(지도 자동 구축)  (0) 2023.02.03
[Softeer] Java - level2 문제풀이(장애물 인식 프로그램)  (0) 2023.01.29
'개발자 세릴리/코딩테스트' 카테고리의 다른 글
  • [Softeer] Java - level2 문제풀이(GBC)
  • [Softeer] Java - level2 문제풀이(전광판)
  • [Softeer] Java - level2 문제풀이(비밀 메뉴)
  • [Softeer] Java - level2 문제풀이(지도 자동 구축)
세릴리
세릴리
  • 세릴리
    세리의 데이터베이스 세상
    세릴리
  • 전체
    오늘
    어제
    • 분류 전체보기 (87)
      • 개발자 세릴리 (65)
        • 비전공자 한 입 지식 (12)
        • 코딩테스트 (24)
        • 스펙업 (15)
        • JAVA (5)
        • 일상 (9)
      • 파이어족 세릴리 (21)
        • 블로그 운영 (3)
        • 각종 양식 공유 (1)
        • 돈되는 정보 공유 (17)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    java 공부
    adsp 벼락치기
    adsp 독학
    adsp 수험표
    현대모비스 코딩테스트
    비전공 개발자
    명품자바프로그래밍 정답
    개발자 공부
    Softeer 문제 풀이
    개발자 이직
    비전공자 개발자
    Java 문제
    JAVA 책 추천
    JAVA 개발공부
    비전공자 개발
    명품자바프로그래밍
    softeer java 풀이
    현대오토에버 코딩테스트
    adsp 자료
    이슈
    백준
    adsp 공부법
    현대자동차 코딩테스트
    개발자되는법
    오늘 이슈
    명품자바프로그래밍 해설
    현대 코테
    현대 코딩테스트
    프로그래밍 공부
    현대오토에버 코테
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
세릴리
[Softeer] Java - level2 문제풀이(회의실 예약)
상단으로

티스토리툴바