본문 바로가기
문제 풀이/소프티어 (Softeer)

[Python] 소프티어 : [21년 재직자 대회 예선] 좌석 관리

by 희조당 2023. 2. 9.
728x90

https://softeer.ai/practice/info.do?idx=1&eid=625 

 

Softeer

연습문제를 담을 Set을 선택해주세요. 취소 확인

softeer.ai


💡 문제 풀이

기본적인 구현 문제이다.

 

이 문제의 핵심은 필요한 좌석을 리턴하는 것이 가장 중요하다. 

앉을 수 있는 자리(0)를 기준으로 현재 사원이 앉아있는 자리(2)와의 거리를 계산해서 전체 중에서 가장 안전도가 높은 좌석을 선택해야 한다.

✔️ 느낀 점

생각보다 훨씬 오래 걸린 문제이다. 메서드를 나눠서 작성해서 단계적으로는 잘 접근했지만 유효한 좌석을 찾아 리턴하는 메서드를 구현하는데 오래 걸렸다.

💻 코드

import sys
input = sys.stdin.readline

moves = [(1,0), (0,1), (-1,0), (0,-1)]

n, m, q = map(int, input().split())

seats = [[0 for _ in range(m)] for _ in range(n)]

checkTable = {} 
eatingUsers = set()

def checkUser(id):
    if id not in checkTable:
        return "NEW"
    return checkTable[id][0]

def getAvailableSeat():
    if (len(eatingUsers) == 0):
        return (0, 0)
    
    x, y = -1, -1
    copied = [seat[:] for seat in seats]

    for i in range(n):
        for j in range(m):
            if copied[i][j] == 0:
                minDistance = int(1e9)
                for u in eatingUsers:
                    a, b = checkTable[u][1]
                    minDistance = min(minDistance, (i-a)**2 + (j-b)**2)
                copied[i][j] = minDistance
    
    safePoint = max(map(max, copied))
    
    if safePoint != 1:
        arr = []
        for x in range(n):
            for y in range(m):
                if copied[x][y] == safePoint:
                    arr.append([x, y])
        x, y = sorted(arr, key=lambda x:(x[0], x[1]))[0]
            
    return x, y

def takeSeat(id, seat):
    eatingUsers.add(id)
    checkTable[id] = ["EAT", seat]
    x, y = seat
    seats[x][y] = 1
    
    for i in range(4):
        nx = x + moves[i][0]
        ny = y + moves[i][1]
        
        if 0 <= nx < n and 0 <= ny < m:
            seats[nx][ny] = -1
    
    print(f"{id} gets the seat ({x+1}, {y+1}).")

def leaveSeat(id):
    eatingUsers.remove(id)
    x, y = checkTable[id][1]
    checkTable[id][0] = "ATE"
    seats[x][y] = 0
    
    for i in range(4):
        nx = x + moves[i][0]
        ny = y + moves[i][1]
        
        if 0 <= nx < n and 0 <= ny < m:
            seats[nx][ny] = 0
    
    print(f"{id} leaves from the seat ({x+1}, {y+1}).")

def inCommand(id):
    status = checkUser(id)
    if status == "NEW":
        seat = getAvailableSeat()
        if seat[0] == -1 and seat[1] == -1:
            print("There are no more seats.")
            return
        
        takeSeat(id, seat)
    elif status == "EAT":
        print(f"{id} already seated.")
    elif status == "ATE":
        print(f"{id} already ate lunch.")

def outCommand(id):
    status = checkUser(id)
    if status == "NEW":
        print(f"{id} didn't eat lunch.")
    elif status == "EAT":
        leaveSeat(id)
    elif status == "ATE":
        print(f"{id} already left seat.")

for _ in range(q):
    command, id = input().split()
    inCommand(int(id)) if command == "In" else outCommand(int(id))

댓글