알고리즘&문제풀이

[Softeer] 21년 재직자 대회 예선 - 회의실 예약

CSE 2025. 12. 11. 09:00

문제

<배경>

배경은 아래에서 확인 가능하다.

더보기

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

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

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

  • 회의실은 $9$시부터 $18$시까지만 사용 가능하다. 모든 회의의 시간은 이 안에 완전히 포함되어야 한다.
  • 회의는 정확히 한 회의실을 연속한 일정 시간동안만 점유한다. 즉 각 회의는 (회의실, 시작 시각, 종료 시각)의 정보로 나타낼 수 있다.
  • 회의의 시작과 종료 시각은 시(時, hour) 단위로만 설정 가능하다.
  • 같은 회의실을 사용하는 회의 시간은 서로 겹칠 수 없다. 여기서 겹친다는 것은, 두 회의 모두에 포함되는 시간이 $1$시간 이상 존재한다는 것을 의미한다. 예를 들어, 10시-12시의 회의와 11시-13시의 회의는 겹치는데, 11시-12시의 시간이 두 회의 모두에 포함되기 때문이다.
  • 한 회의가 끝나는 시각에, 같은 회의실에서 다른 회의가 시작하는 것은 허용된다. 이 경우 두 회의가 겹치지 않기 때문이다.
  • 길이가 0인 회의, 즉 시작 시각과 종료 시각이 동일한 회의는 예약된 바 없으며, 새롭게 잡을 수도 없다.

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

<입력>

<출력>

<예시>


풀이

따져봐야하는 시간은 9시부터이지만 약간의 공간낭비를 하고 대신 편의성을 얻을 목적으로,

해당 시간에 회의실이 비어있는지 표시해주는 리스트로 그냥 길이 19짜리 리스트를 사용하자.

0이면 빈 회의실, 1이면 사용중인  회의실이다.

인덱스를 시간과 바로 매칭을 하기 위해 18+1의 길이를 사용했다.

첫 n개의 입력은 회의실 이름이 주어지므로 {회의실이름 : 시간리스트} 방식의 딕셔너리를 사용했다.

 

그 다음 m줄은 회의실들의 일정이 나오는데, 시간리스트의 해당 시간대 값들을 1로 바꿔 사용중임을 나타냈다.

최종 출력에서 회의실의 이름에 따라 오름차순 정렬을 해야하므로 room = sorted(room.items())를 실행했다.

{'이름':'시간리스트', '이름':'시간리스트',...} 형태에서 [('이름','시간리스트'), ('이름','시간리스트'),...]형태로 바뀌고 정렬이 된다.

n,m = map(int,input().split())
room = {}
for i in range(n): #회의실 이름 저장
    name = input()
    room[name] = [0]*18+[1]

for i in range(m): #회의실별 예약시간 처리
    name, start, end = input().split()
    start = int(start)
    end = int(end)
    for j in range(start, end):
        room[name][j] = 1

room = sorted(room.items()) #회의실 이름순 정렬

 

이제 회의실이 빈 시간대를 찾아야한다.

빈 시간대를 [비기 시작한 시간, 다음사용이 시작될 시간]의 형태로 temp라는 리스트에 저장할 계획이다.

위의 시간리스트에서 0과 1이 바뀌는 지점이 중요한데, 0에서 1로 바뀌었는지, 1에서 0으로 바뀌었는지 알기 위해 current라는 변수를 도입했다.

시작 current값을 1로 놓는 것이 빈 시간대를 찾는데는 더 수월하다.

 

1에서 0으로 바뀌었다면 이용이 가능해진 시간대이므로 이 때의 값과,

0에서 1로 바뀌었다면 다른 예약이 있는 시간대이므로 이 때의 값을 묶어 temp에 저장한다.

 

이제 출력형식에 맞게 출력해주면 된다.

for i in range(n):
    current = 1
    temp = []
    for j in range(9,19): #우리가 관심있는 시간대
        if current == 1 and room[i][1][j] == 0:
            sTime = j
            current = 0
        elif current == 0 and room[i][1][j] == 1:
            fTime = j
            current = 1
            temp.append([sTime,fTime])

    print(f'Room {room[i][0]}:')
    if len(temp) == 0:
        print('Not available')
    else:
        print(len(temp),'available:') 
        for j in range(len(temp)):
            print(f'{temp[j][0]:02d}-{temp[j][1]}')
    if i != n-1: #마지막이 아닐 때
        print('-----')