코딩테스트/백준

[백준] 17259 - 선물이 넘쳐흘

rlatotquf45 2024. 11. 22. 16:37
728x90
반응형

문제 링크

https://www.acmicpc.net/problem/17259

문제 요약

 

  • 욱제가 팬들에게 선물을 주기 위해 ⊐ 모양 컨베이어 벨트가 있는 B×B 크기의 공장을 운영합니다.
  • M개의 선물이 컨베이어 벨트를 따라 이동하고, 벨트는 매 초마다 한 칸씩 움직입니다.
  • 벨트에 인접한 칸에 직원이 배치되어 있으며, 직원들은 자신이 설정된 시간을 기준으로 선물을 포장할 수 있습니다.
  • 벨트의 끝까지 포장되지 않은 선물은 폐기됩니다.
  • 포장된 선물의 총 개수를 계산해야 합니다.

 

푼 방법

  1. 데이터 구조 초기화:
    • world: 공장의 상태를 나타내는 2D 배열, 각 칸에 선물이 있는지 여부를 표시.
    • employees: 직원클래스, 각 직원의 위치와 상태를 저장.
  2. 컨베이어 벨트의 동작:
    • 컨베이어 벨트는 매 초마다 이동하며, 이동 규칙은 ⊐ 모양을 따름.
    • 벨트의 시작 지점(0, 0)에 새로운 선물을 놓고, 끝 지점(b-1, 0)에 도달한 선물은 폐기.
  3. 직원의 행동:
    • 각 직원은 자신의 위치에서 상,하, 우로 인접한 벨트 칸에 선물이 있는지 확인.
    • 선물이 있다면 포장을 시작하며, 포장에 걸리는 시간(T)이 지나면 다음 선물을 포장.
  4. 시뮬레이션 반복:
    • 선물 M개가 모두 벨트에 올라간 이후에도 벨트 위에 남아있는 선물이 없을 때까지 시뮬레이션을 반복.
    • 선물이 포장되거나 폐기될 때까지 벨트를 계속 움직임.
  5. 결과 계산:
    • 컨베이어에 선물 다 떨어지면 포장한 선물들 + 현재 포장하고 있는 사람들 수 로 결과출력

정답 코드

import sys

class Employee:
    
    def __init__(self, y = -1, x = -1, wt = -1, wk = 0):
        self.pos_y = y
        self.pos_x = x
        self.work_time = wt
        self.working = wk
        self.point=0
        
b, n, m = map(int, sys.stdin.readline().split())

employees=[]      
world = [[False for _ in range(b)] for _ in range(b)]
ans = 0

for _ in range(n):
    r, c, t = map(int, sys.stdin.readline().split())
    e = Employee(r, c, t)
    employees.append(e)

def conveyer_move(time):
    if world[b-1][0]:
        world[b-1][0]=False
    for i in range(b-1):
        if world[b-1][i+1]:
            world[b-1][i+1] = False
            world[b-1][i] = True
            
    for i in range(b-1, 0, -1):
        if world[i-1][b-1]:
            world[i-1][b-1] = False
            world[i][b-1] = True
            
    for i in range(b-1, 0, -1):
        if world[0][i-1]:
            world[0][i-1] = False 
            world[0][i] = True
    if time < m:
        world[0][0] = True
        
dir = [[1, 0], [0, 1], [-1,0]]
        
def employee_chk():
    for e in employees:
        if e.working == e.work_time:
            e.working = 0
            e.point+=1
        if e.working > 0 : 
            e.working+=1
            continue
        
        ny, nx = 0, 0
        for dy, dx in dir:
            ny = e.pos_y + dy
            nx = e.pos_x + dx

            if world[ny][nx]:
                world[ny][nx] = False
                e.working += 1
                break
        

def conv_chk():
    for i in range(b):
        for j in range(b):
            if world[i][j] == True:
                return True
    return False

def print_conv():
    for i in range(b):
        print(world[i])

def print_employee():
    for i, e in enumerate(employees):
        print(i, e.work_time, e.working, e.point)
        
for i in range(m):
    # print(i+1)
    conveyer_move(i)
    employee_chk()
    # print_conv()
    # print()
    
t = 1
while True:
    if not conv_chk():
        break
    # print(i+t+1)
    conveyer_move(m)
    employee_chk()
    # print_conv()
    # print()
    # q = input()
    t+=1
        
for e in employees:
    ans+=e.point
    if e.working > 0:
        ans+=1

print(ans)

 

728x90
반응형