본문 바로가기

알고리즘/소프티어

[파이썬] Softeer 연습문제 #24. [21년 재직자 대회 예선] 회의실 예약 완벽해설

문제

 

https://softeer.ai/practice/6266

 

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

회사에는 N개의 회의실이 있다. 수많은 팀이 모여 토론하고 업무를 처리하기 위해서는 회의실이 필수적이다. 내부망에 아주 간단한 회의실 예약 시스템이 있지만 편의성이 매우 떨어진다. 단순

softeer.ai

 

 

해설

 

이 문제는 로직을 논리적으로 하나하나 짤 수 있는가, 그리고 지시한대로 결과값을 잘 출력하는지를 보기 위한 문제이다. 그래서 따로 어떤 효율적인 알고리즘이 존재하지 않고, 정신줄 놓지 않고 논리대로 코드를 짜면 문제없이 풀 수 있다.

 

그래서 이번 내용은 따로 해설을 하지 않고 코드에 주석으로써 한줄한줄 잘 설명해두었다.

 

다만 코드를 짤 때 유의해야 될 점으로는, for 루프 안에서 출력문을 언제 담아야 하는지에 대해서 논리적으로 잘 생각해보고, 또 각각의 루프에 있어서 초기화되어야 할 변수가 어떤 것인지 잘 생각해봐야만 되는 것 같다.

 

 

코드
import sys
import math

# 회의실의 수(N)와 예약된 회의의 수(M)을 받는다.
N, M = map(int, sys.stdin.readline().split())

conf_timetable = {}

# N개의 회의실 이름을 받아들이고 시간표를 세팅한다.
for _ in range(N):
  # 각각의 회의실 이름을 key로, 시간표를 value로 설정
  conf_name = input()
  conf_timetable[conf_name] = [0 for _ in range(9)]

# [0 for _ in range(9)]은 9시 ~ 18시를 한시간 간격으로 표현한 리스트

# 시간을 시간표의 인덱스로 변경해주는 함수
def mapping(time):
  return time-9

# 회의실 이름 r, 시작 시간 s, 그리고 종료 시각 t를 받아들여 시간표에 채운다.
for _ in range(M):
  r, s, t = sys.stdin.readline().split()
  # 문자형을 숫자로 변경해준다.
  s = int(s)
  t = int(t)
  
  # 회의가 있는 시간을 1로 채운다.
  conf_timetable[r][mapping(s):mapping(t)] = [1]*(mapping(t)-mapping(s))

# 회의실 이름을 오름차순으로 정렬한다.
keys = conf_timetable.keys()
sorted_keys = sorted(keys)

# 회의실 시간표에서 이용 가능 시간을 측정하기 위한 보조 변수
begin_time = math.inf
# 출력문을 저장할 리스트
print_list = []

# 이제 회의실 이름과 회의실 시간표를 토대로 출력하는 코드를 작성한다.
for key in sorted_keys:
  # 첫째 줄에는 "Room 회의실이름:"을 출력한다.
  print("Room "+key+":")
  # 출력문을 매번 초기화해준다
  print_list = []
    
  # 이용 가능 시간들(시간표에서 0인 지점들)을 탐색한다.
  for time_index in range(len(conf_timetable[key])):
    # 이용 가능 시간일 경우
    if (conf_timetable[key][time_index] == 0):
      # 시작 지점을 이전 루프의 시작 인덱스와 현재 시간 인덱스 중 최소값으로 갱신한다.
      begin_time = min(begin_time, time_index)
      # 만약 마지막 시간에 도달했을 경우 시작시간부터 마지막 시간까지의 출력문을 넣어준다.
      if (time_index == len(conf_timetable[key])-1):
        # 출력문 준비
        begin_time_str = str(begin_time+9)
        end_time_str = str(time_index+9+1)
        # 숫자가 한자리로 이루어졌을 경우 앞에 "0"을 붙인다.
        if (len(begin_time_str) == 1):
          begin_time_str = "0" + begin_time_str
        # 끝나는 시간은 어차피 18시, 즉 두자리이므로 더할 필요가 없다.
        print_list.append(begin_time_str + "-" + end_time_str)
    # 이용 불가능 시간일 경우
    else:
      begin_time = min(begin_time, time_index)
      # 만약 시작 시간 인덱스가 현재 인덱스랑 동일한 경우
      if (begin_time == time_index):
        # 이 경우는 이전 루프에서도 1임.
        # 시간을 다시 초기화해주고 다음 루프를 돌린다.
        begin_time = math.inf
        continue
      else: # 이전 루프에서 0인 경우
        # 출력문 준비
        begin_time_str = str(begin_time+9)
        end_time_str = str(time_index+9)
        # 한 숫자일 경우 앞에 "0"을 붙인다.
        if (len(begin_time_str)==1):
          begin_time_str = "0" + begin_time_str
        if (len(end_time_str)==1):
          end_time_str = "0" + end_time_str
        
        # 출력문을 넣는다.
        print_list.append(begin_time_str + "-" + end_time_str)
      # 시작 시간 인덱스를 inf로 초기화해준다. (다른 빈 시간을 찾아야 하므로)
        begin_time = math.inf
  
  # 이제 각 회의실마다 이용가능 여부와 이용가능 시간을 출력해준다.
  # 이용시간이 존재하지 않을 때
  if (len(print_list)==0):
    print("Not available")
  # 이용시간이 존재할 때
  else:
    print(str(len(print_list)) + " available:")
  
  for p in print_list:
    print(p)

  if (key != sorted_keys[-1]):
      print("-----")

 

 

결과