μ•Œκ³ λ¦¬μ¦˜/κ·Έλž˜ν”„

[λ°±μ€€ 7576 πŸ₯‡] ν† λ§ˆν† 

1eehyunji 2023. 7. 12. 01:21

문제

철수의 ν† λ§ˆν†  농μž₯μ—μ„œλŠ” ν† λ§ˆν† λ₯Ό λ³΄κ΄€ν•˜λŠ” 큰 μ°½κ³ λ₯Ό κ°€μ§€κ³  μžˆλ‹€. ν† λ§ˆν† λŠ” μ•„λž˜μ˜ κ·Έλ¦Όκ³Ό 같이 격자 λͺ¨μ–‘ μƒμžμ˜ 칸에 ν•˜λ‚˜μ”© λ„£μ–΄μ„œ 창고에 λ³΄κ΄€ν•œλ‹€.

창고에 λ³΄κ΄€λ˜λŠ” ν† λ§ˆν† λ“€ μ€‘μ—λŠ” 잘 읡은 것도 μžˆμ§€λ§Œ, 아직 읡지 μ•Šμ€ ν† λ§ˆν† λ“€λ„ μžˆμ„ 수 μžˆλ‹€. 보관 ν›„ ν•˜λ£¨κ°€ μ§€λ‚˜λ©΄, 읡은 ν† λ§ˆν† λ“€μ˜ μΈμ ‘ν•œ 곳에 μžˆλŠ” 읡지 μ•Šμ€ ν† λ§ˆν† λ“€μ€ 읡은 ν† λ§ˆν† μ˜ 영ν–₯을 λ°›μ•„ 읡게 λœλ‹€. ν•˜λ‚˜μ˜ ν† λ§ˆν† μ˜ μΈμ ‘ν•œ 곳은 μ™Όμͺ½, 였λ₯Έμͺ½, μ•ž, λ’€ λ„€ λ°©ν–₯에 μžˆλŠ” ν† λ§ˆν† λ₯Ό μ˜λ―Έν•œλ‹€. λŒ€κ°μ„  λ°©ν–₯에 μžˆλŠ” ν† λ§ˆν† λ“€μ—κ²ŒλŠ” 영ν–₯을 μ£Όμ§€ λͺ»ν•˜λ©°, ν† λ§ˆν† κ°€ 혼자 μ €μ ˆλ‘œ μ΅λŠ” κ²½μš°λŠ” μ—†λ‹€κ³  κ°€μ •ν•œλ‹€. μ² μˆ˜λŠ” 창고에 λ³΄κ΄€λœ ν† λ§ˆν† λ“€μ΄ 며칠이 μ§€λ‚˜λ©΄ λ‹€ 읡게 λ˜λŠ”μ§€, κ·Έ μ΅œμ†Œ 일수λ₯Ό μ•Œκ³  μ‹Άμ–΄ ν•œλ‹€.

ν† λ§ˆν† λ₯Ό 창고에 λ³΄κ΄€ν•˜λŠ” 격자λͺ¨μ–‘μ˜ μƒμžλ“€μ˜ 크기와 읡은 ν† λ§ˆν† λ“€κ³Ό 읡지 μ•Šμ€ ν† λ§ˆν† λ“€μ˜ 정보가 μ£Όμ–΄μ‘Œμ„ λ•Œ, 며칠이 μ§€λ‚˜λ©΄ ν† λ§ˆν† λ“€μ΄ λͺ¨λ‘ μ΅λŠ”μ§€, κ·Έ μ΅œμ†Œ 일수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λΌ. 단, μƒμžμ˜ 일뢀 μΉΈμ—λŠ” ν† λ§ˆν† κ°€ λ“€μ–΄μžˆμ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€.

μž…λ ₯

첫 μ€„μ—λŠ” μƒμžμ˜ 크기λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 두 μ •μˆ˜ M,N이 μ£Όμ–΄μ§„λ‹€. M은 μƒμžμ˜ κ°€λ‘œ 칸의 수, N은 μƒμžμ˜ μ„Έλ‘œ 칸의 수λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 단, 2 ≤ M,N ≤ 1,000 이닀. λ‘˜μ§Έ μ€„λΆ€ν„°λŠ” ν•˜λ‚˜μ˜ μƒμžμ— μ €μž₯된 ν† λ§ˆν† λ“€μ˜ 정보가 μ£Όμ–΄μ§„λ‹€. 즉, λ‘˜μ§Έ 쀄뢀터 N개의 μ€„μ—λŠ” μƒμžμ— λ‹΄κΈ΄ ν† λ§ˆν† μ˜ 정보가 μ£Όμ–΄μ§„λ‹€. ν•˜λ‚˜μ˜ μ€„μ—λŠ” μƒμž κ°€λ‘œμ€„μ— λ“€μ–΄μžˆλŠ” ν† λ§ˆν† μ˜ μƒνƒœκ°€ M개의 μ •μˆ˜λ‘œ μ£Όμ–΄μ§„λ‹€. μ •μˆ˜ 1은 읡은 ν† λ§ˆν† , μ •μˆ˜ 0은 읡지 μ•Šμ€ ν† λ§ˆν† , μ •μˆ˜ -1은 ν† λ§ˆν† κ°€ λ“€μ–΄μžˆμ§€ μ•Šμ€ 칸을 λ‚˜νƒ€λ‚Έλ‹€.

ν† λ§ˆν† κ°€ ν•˜λ‚˜ 이상 μžˆλŠ” 경우만 μž…λ ₯으둜 μ£Όμ–΄μ§„λ‹€.

좜λ ₯

μ—¬λŸ¬λΆ„μ€ ν† λ§ˆν† κ°€ λͺ¨λ‘ 읡을 λ•ŒκΉŒμ§€μ˜ μ΅œμ†Œ λ‚ μ§œλ₯Ό 좜λ ₯ν•΄μ•Ό ν•œλ‹€. λ§Œμ•½, μ €μž₯될 λ•ŒλΆ€ν„° λͺ¨λ“  ν† λ§ˆν† κ°€ μ΅μ–΄μžˆλŠ” μƒνƒœμ΄λ©΄ 0을 좜λ ₯ν•΄μ•Ό ν•˜κ³ , ν† λ§ˆν† κ°€ λͺ¨λ‘ μ΅μ§€λŠ” λͺ»ν•˜λŠ” 상황이면 -1을 좜λ ₯ν•΄μ•Ό ν•œλ‹€.

λ¬Έμ œν’€μ΄

import sys
from collections import deque

m,n=map(int, sys.stdin.readline().split(' '))
tomato=[list(map(int, sys.stdin.readline().split(' '))) for _ in range(n)]

# ν˜„μž¬ 읡은 ν† λ§ˆν† μ˜ μœ„μΉ˜μ™€ ν˜„μž¬ μ‹œκ°„μ„ 큐에 μ €μž₯
# 빈 μΉΈ 인 경우 μ €μž₯
ripen_tomato=deque()
not_exist=0
for i in range(n):
    for j in range(m):
        if tomato[i][j]==1:
            ripen_tomato.append((i,j,0))
        elif tomato[i][j]==-1:
            not_exist+=1

# μ²˜μŒλΆ€ν„° λͺ¨λ“  ν† λ§ˆν† κ°€ μ΅μ–΄μžˆλŠ” 경우 0 좜λ ₯ν•˜κ³  μ’…λ£Œ
num_of_ripen_tomato=len(ripen_tomato)
if num_of_ripen_tomato==(m*n-not_exist):
    print(0)
    sys.exit(0)


def spread_ripe():
    global ripen_tomato, time
    directions=[(1,0),(0,1),(-1,0),(0,-1)]
    #visited=[[0]*m for _ in range(n)]
    add_ripen_tomato=0
    while ripen_tomato and ripen_tomato[0][2]==time:
        y, x, t=ripen_tomato.popleft()
        for di in directions:
            dy=y+di[0]
            dx=x+di[1]
            if 0<=dy<n and 0<=dx<m and tomato[dy][dx]==0:
                tomato[dy][dx]=1
                ripen_tomato.append((dy,dx,t+1))
                add_ripen_tomato+=1

    if add_ripen_tomato:
        return add_ripen_tomato
    else:
        return 0

time=0
while num_of_ripen_tomato<(n*m-not_exist):
    # 읡은 ν† λ§ˆν† μ™€ μΈμ ‘ν•œ 읡지 μ•Šμ€ ν† λ§ˆν† λ‘œ μ „νŒŒ
    add_tomato=spread_ripe()
    if add_tomato==0:
        print(-1)
        sys.exit(0)
    num_of_ripen_tomato+=add_tomato
    time+=1

print(time)

초기 μƒνƒœμ— 읡은 ν† λ§ˆν† μ˜ μœ„μΉ˜μ™€ μ‹œκ°„μ„ 큐에 μ €μž₯ν–ˆλ‹€. 그리고, 전체 읡어야 ν•˜λŠ” ν† λ§ˆν† μ˜ 개수λ₯Ό κ΅¬ν•˜κΈ° μœ„ν•΄μ„œ ν† λ§ˆν† κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 칸의 κ°œμˆ˜λ„ not_exist λ³€μˆ˜μ— μ €μž₯ν•΄λ’€λ‹€. 

 

λ¨Όμ € 제일 μ²˜μŒμ— ν† λ§ˆν† μ˜ μƒνƒœκ°€ μ €μž₯된 tomatoλ₯Ό νƒμƒ‰ν•˜λ©΄μ„œ 큐에 μΆ”κ°€ν•΄μ€€ 읡은 ν† λ§ˆν† μ˜ 개수λ₯Ό num_of_ripen_tomato λ³€μˆ˜μ— μ €μž₯ν•΄μ£Όκ³ , 읡은 ν† λ§ˆν† μ˜ κ°œμˆ˜κ°€ 읡어야 ν•˜λŠ” ν† λ§ˆν† μ˜ 총 개수(n*m-not_exist)와 λ™μΌν•œμ§€ 체크해쀬닀. λ™μΌν•˜λ‹€λ©΄ 0을 좜λ ₯ν•˜κ³  ν”„λ‘œκ·Έλž¨μ„ μ’…λ£Œν•œλ‹€. 

 

μ‹œκ°„λŒ€λ³„λ‘œ 읡은 ν† λ§ˆν† μ˜ 개수λ₯Ό num_of_ripen_tomato λ³€μˆ˜μ— μΆ”κ°€ν•˜λ©΄μ„œ, 읡어야 ν•˜λŠ” ν† λ§ˆν† μ˜ 총 κ°œμˆ˜λ³΄λ‹€ μž‘μ„ λ™μ•ˆ while문을 λ°˜λ³΅ν•˜λ„λ‘ ν–ˆλ‹€. 

μš°μ„  spread_ripen() ν•¨μˆ˜λ₯Ό ν†΅ν•΄μ„œ ν† λ§ˆν† λ₯Ό μ‹œκ°„λŒ€λ³„λ‘œ 읡은 ν† λ§ˆν† μ˜ 개수λ₯Ό λ°˜ν™˜ν•΄μ„œ add_tomato λ³€μˆ˜μ— λ‹΄μ•„ num_of_ripen_tomato에 λ”ν•˜λ„λ‘ ν–ˆλ‹€. 그리고 time λ³€μˆ˜λ₯Ό +1ν•΄μ€€λ‹€. 

 

μ—¬κΈ°μ„œ, add_tomato의 값이 0이면, 즉 spread_ripen() ν•¨μˆ˜κ°€ 0을 λ°˜ν™˜ν•˜λ©΄ 더 이상 읡힐 수 μžˆλŠ” ν† λ§ˆν† κ°€ μ—†λ‹€λŠ” 뜻인데 num_of_ripen_tomatoκ°€ λͺ©ν‘œμΉ˜μ— λ„λ‹¬ν•˜μ§€ λͺ»ν•œ μƒνƒœμ΄λ―€λ‘œ λͺ¨λ“  ν† λ§ˆν† λ₯Ό 읡힐 μˆ˜λŠ” μ—†λ‹€λŠ” κ²ƒμœΌλ‘œ κ°„μ£Όν•˜κ³  -1을 좜λ ₯ν•˜κ³  ν”„λ‘œκ·Έλž¨μ„ μ’…λ£Œν•œλ‹€. 

 

spread_ripen() ν•¨μˆ˜μ—μ„œλŠ” 읡은 ν† λ§ˆν†  데이터λ₯Ό μ €μž₯ν•˜κ³  μžˆλŠ” ripen_tomato 큐λ₯Ό  bfsλ₯Ό μ΄μš©ν•΄μ„œ νƒμƒ‰ν•˜λ©΄μ„œ μΈμ ‘ν•˜κ³  μ΅μ§€μ•Šμ€ ν† λ§ˆν† λ“€μ„ μœ„μΉ˜μ™€ ν˜„μž¬μ‹œκ°„+1ν•œ 값을 ripen_tomato 큐에 λ„£μ–΄μ€€λ‹€.

μ—¬κΈ°μ„œ  while문의 쑰건이 ripen_tomato의 첫번째 κ°’μ˜ 2번째 μΈλ±μŠ€κ°€ ν˜„μž¬ μ‹œκ°„μ„ λ‚˜νƒ€λ‚΄λŠ” time λ³€μˆ˜μ™€ λ™μΌν•œ λ™μ•ˆλ§Œ while문을 λ°˜λ³΅ν•˜λ„λ‘ ν•˜λ©΄μ„œ, ν˜„μž¬ μ²˜λ¦¬ν•΄μ€˜μ•Ό ν•˜λŠ” ν† λ§ˆν† λ“€λ§Œ μ²˜λ¦¬ν•˜λ„λ‘ ν–ˆλ‹€. 그리고 이 κ³Όμ •μ—μ„œ 읡은 ν† λ§ˆν† μ˜ 개수λ₯Ό λ°˜ν™˜ν•œλ‹€. 

 

읡은 ν† λ§ˆν† μ˜ κ°œμˆ˜κ°€ λͺ©ν‘œμΉ˜(읡어야 ν•˜λŠ” ν† λ§ˆν† μ˜ 총 개수)에 λ„λ‹¬ν•˜λ©΄ while문을 λΉ μ Έλ‚˜μ™€μ„œ time을 좜λ ₯ν•œλ‹€.