Algorithm & Data Structure/Programmers

[Programmers]Python_호텔 방 배정

ju_young 2021. 4. 26. 20:06
728x90
문제

 

문제 설명

 

"스노우타운"에서 호텔을 운영하고 있는 "스카피"는 호텔에 투숙하려는 고객들에게 방을 배정하려 합니다. 호텔에는 방이 총 k개 있으며, 각각의 방은 1번부터 k번까지 번호로 구분하고 있습니다. 처음에는 모든 방이 비어 있으며 "스카피"는 다음과 같은 규칙에 따라 고객에게 방을 배정하려고 합니다.

  1. 한 번에 한 명씩 신청한 순서대로 방을 배정합니다.
  2. 고객은 투숙하기 원하는 방 번호를 제출합니다.
  3. 고객이 원하는 방이 비어 있다면 즉시 배정합니다.
  4. 고객이 원하는 방이 이미 배정되어 있으면 원하는 방보다 번호가 크면서 비어있는 방 중 가장 번호가 작은 방을 배정합니다.

예를 들어, 방이 총 10개이고, 고객들이 원하는 방 번호가 순서대로 [1, 3, 4, 1, 3, 1] 일 경우 다음과 같이 방을 배정받게 됩니다.

 

원하는 방 번호 배정된 방 번호
1 1
3 3
4 4
1 2
3 5
1 6

 

전체 방 개수 k와 고객들이 원하는 방 번호가 순서대로 들어있는 배열 room_number가 매개변수로 주어질 때, 각 고객에게 배정되는 방 번호를 순서대로 배열에 담아 return 하도록 solution 함수를 완성해주세요.

 

제한 사항

 

  • k는 1 이상 1012 이하인 자연수입니다.
  • room_number 배열의 크기는 1 이상 200,000 이하입니다.
  • room_number 배열 각 원소들의 값은 1 이상 k 이하인 자연수입니다.
  • room_number 배열은 모든 고객이 방을 배정받을 수 있는 경우만 입력으로 주어집니다.
    • 예를 들어, k = 5, room_number = [5, 5] 와 같은 경우는 방을 배정받지 못하는 고객이 발생하므로 이런 경우는 입력으로 주어지지 않습니다.

 

코드

 

Recursive한 풀이

 

import sys
#recursionlimit을 지정해 주지않으면 런타임 에러가 뜨는 까다로운 프로그래머스...
sys.setrecursionlimit(10000000)

def solution(k, room_number):
    def dfs(n, rooms):
    	#비어있는 방이면 해당 방 번호의 다음 번호를 저장해놓는다
        if n not in rooms:
            rooms[n] = n + 1
            return n
        
        #현재 번호의 방이 비어있지않으면 해당 번호에 저장되어 있는 번호로 가본다.
        empty_room = dfs(rooms[n], rooms)
        #비어있는 방을 찾았다! 찾은 방은 현재 고객이 들어가야하니 다음 방을 저장해준다.
        rooms[n] = empty_room + 1
        return empty_room
    
    rooms = {} #현재 방 번호의 다음 번호 중 비어있는 방 번호를 저장
    answer = []
    for i in room_number:
        answer.append(dfs(i, rooms)) #배정된 방 번호 기록
            
    return answer

 

Iterative한 풀이

 

def solution(k, room_number):
    rooms = {}
    answer = []
    for n in room_number:
        visited = [n] #비어있는 방을 찾기 전 방문해본 방들
        #비어있는 방을 찾을 때까지 반복
        while n in rooms:
            n = rooms[n]
            visited.append(n)
        answer.append(n)
        #방문했던 방들에 현재 고객이 찾은 비어있는 방 번호의 다음 번호를 저장
        for i in visited:
            rooms[i] = n + 1
    return answer

 

 

풀이

 

예제 #1

 

k = 10

room_number = [1,3,4,1,3,1]

 

첫 번째로 이중 for문을 사용하여 실행했지만 효율성에서 시간초과, 두 번째로 recursive하게 방 번호마다 True, Flase만으로 check하여 실행하였다만 시간초과...

 

간단하게 풀이법을 설명하자만 각 방마다 표지판을 달아주면 된다.

아래 그림은 편의상 6번까지만 표현한 진행 과정을 나타내고 있다.

 

진행 과정

 

1. 첫 번째 고객은 1번 방에 배정받고 싶다. -> 1번 방이 빈 방이므로 바로 배정 받는다.

 

2. 두 번째 고객은 3번 방에 배정받고 싶다. -> 3번 방이 빈 방이므로 바로 배정 받는다.

 

3. 세 번째 고객은 4번 방에 배정받고 싶다. -> 4번 방이 빈 방이므로 바로 배정 받는다.

 

4. 네 번째 고객은 1번 방에 배정받고 싶다. -> 이미 1번 방에 있던 고객이 2번 방으로 가보라고 한다. -> 2번 방이 비어있으므로 배정 받는다. -> 이전에 방문했던 1번 방에 "2번 방으로 배정 받을테니 다음에 오는 사람에게는 3번으로 가라고 하세요."라고 전달한다.

 

5. 다섯 번째 고객은 3번 방에 배정 받고 싶다. -> 이미 3번 방에 있던 고객이 4번 방으로 가보라고 한다. -> 이미 4번 방에 있던 고객이 5번 방에 가보라고 한다. -> 5번 방이 비어있으므로 배정 받는다. -> 이전에 방문했던 3, 4번 방에 "5번 방으로 배정 받을테니 다음에 오는 사람에게는 6번으로 가라고 하세요."라고 전달한다.

 

6. 여섯 번째 고객은 1번 방에 배정 받고 싶다. -> 이미 1번 방에 있던 고객이 3번 방으로 가보라고 한다. -> 이미 3번 방에 있던 고객이 6번 방으로 가보라고 한다. -> 6번 방이 비어있으므로 배정 받는다.-> 이전에 방문했던 1, 3번 방에 "6번 방으로 배정 받을테니 다음에 오는 사람에게는 7번으로 가라고 하세요."라고 전달한다.

 

7. 모든 고객이 방을 배정 받았다.

728x90