백준 17144 안녕 미세먼지 (Python)

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





솔루션 1

# https://www.acmicpc.net/problem/17144

R,C,T = map(int,input().split())
array = (list(map(int,input().split())) for _ in range(R))
machine = ()

for r in range(R):
    if array(r)(0) == -1:
        machine.append((r,0))
        machine.append((r+1,0))
        break

dx = (0,0,1,-1)
dy = (1,-1,0,0)

def spread(array):
    global machine
    new_array = ((0)*C for _ in range(R))

    for mx,my in machine:
        new_array(mx)(my) = -1

    for x in range(R):
        for y in range(C):
            if array(x)(y)>0: # 확산가능
                dir_cnt = 0
                for i in range(4):
                    nx = x + dx(i)
                    ny = y + dy(i)
                    if 0<=nx<R and 0<=ny<C:
                        if array(nx)(ny) != -1:
                            dir_cnt +=1
                            new_array(nx)(ny) += array(x)(y)//5
                new_array(x)(y) += (array(x)(y) - (array(x)(y)//5 * dir_cnt))

    return new_array

def air_work(new_array):
    global machine
    # 위쪽 공기청정기는 반시계 방향 순환

    up_x, up_y = machine(0)(0), machine(0)(1)
    down_x,down_y = machine(1)(0), machine(1)(1)

    # 위쪽 공기청정기(반시계 회전)

    # 왼쪽
    for i in range(up_x-1,0,-1):
        new_array(i)(0) = new_array(i-1)(0)

    # 위쪽
    for i in range(C-1):
        new_array(0)(i)= new_array(0)(i+1)

    # 오른쪽
    for i in range(up_x):
        new_array(i)(C-1) = new_array(i+1)(C-1)

    # 중앙
    for i in range(C-1,1,-1):
        new_array(up_x)(i) = new_array(up_x)(i-1)
    new_array(up_x)(1) = 0

    # 아래쪽 공기청정기(시계방향)
    # 왼쪽
    for i in range(down_x+1,R-1):
        new_array(i)(0) = new_array(i+1)(0)

    # 아래쪽
    for i in range(C-1):
        new_array(R-1)(i)= new_array(R-1)(i+1)

   # 오른쪽
    for i in range(R-1, down_x, -1):
        new_array(i)(C-1) = new_array(i - 1)(C-1)

   # 중앙
    for i in range(C-1, 1, -1):
        new_array(down_x)(i) = new_array(down_x)(i - 1)
    new_array(down_x)(1) = 0

    return new_array

def check(array):
    answer = 0
    for x in array:
        answer += sum(x)
    return answer + 2 # -1 2개

def solve(array):

    for _ in range(T):
        new_array=spread(array) # 미세먼지 확산
        array=air_work(new_array) # 공기청정기 작동

    ans=check(array) # 방에 남은 미세먼지 전체 양 출력
    return ans

print(solve(array))

솔루션 2

import sys
from collections import deque
R,C,T = map(int,input().split())
array = (list(map(int,input().split())) for i in range(R))
# 공기청정기 좌표
air = () # 첫번째꺼 윗놈, 두번쨰꺼 아랫놈
for i in range(R):
    if array(i)(0) == -1:
        air.append((i,0))

dx = (-1,1,0,0)
dy = (0,0,-1,1)



def bfs():
    q = deque(())
    new_array = ((0)*C for _ in range(R))

    # 처음에 확산 가능한 곳 전부 queue 에 삽입
    for i in range(R):
        for j in range(C):
            if array(i)(j) >0:
                q.append((i,j,array(i)(j))) # 좌표랑 미세먼지 양 삽입

    while q: # 큐에 있는 수 만큼 확산
        x,y,quant = q.popleft() # x,y, 미세먼지 양
        cnt = 0 # 카운팅
        for i in range(4): # 4가지 방향 가능
            nx = x + dx(i)
            ny = y + dy(i)
            
            if nx >=0 and nx <R and ny>=0 and ny<C:# 범위 안에 들면
                if air(1) != (nx,ny) and air(0) != (nx,ny) : 
                    new_array(nx)(ny) +=  (quant //5)
                    cnt +=1

        # cnt 개수 다 세었으면
        array(x)(y) -= cnt*(quant//5)
    
    # 확산 끝
    for i in range(R):
        for j in range(C):
            array(i)(j) += new_array(i)(j)


def air_work():
    # 바로 위 잡아먹기
    array(air(0)(0)-1)(air(0)(1)) = 0
    # 바로 아래 잡아먹기
    array(air(1)(0)+1)(air(1)(1)) = 0
    
    # 위 -> 아래
    for i in range(air(0)(0)-1,0,-1):
        array(i)(0) = array(i-1)(0)
    # 바로 아래 잡아먹기
    array(air(1)(0)+1)(air(0)(1)) = 0
    
    # 아래 -> 위
    for i in range(air(1)(0)+1,R-1):
        array(i)(0)=array(i+1)(0) 

    # 위 => 오른에서 왼, 아래 => 오른에서 왼
    for i in range(C-1):
        array(0)(i) = array(0)(i+1)
        array(R-1)(i) = array(R-1)(i+1)

    # 끝에 열 위, 위로 가는거 처리
    for i in range(air(0)(0)):
        array(i)(C-1) = array(i+1)(C-1)

    # 끝에 열 아래, 아래로 가는 거 처리
    for i in range(R-1,air(1)(0),-1):
        array(i)(C-1) = array(i-1)(C-1)

    # 왼쪽에서 오른쪽 밀기
    for i in range(C-1,1,-1):
        array(air(0)(0))(i)=array(air(0)(0))(i-1)
        array(air(1)(0))(i)=array(air(1)(0))(i-1)
    
    # 공기청정기 나오는 곳은 0이 되어야함
    array(air(0)(0))(1) = 0 
    array(air(1)(0))(1) = 0
    
def check():
    result = 0
    for i in range(R):
        for j in range(C):
            if array(i)(j) >0 :    
                result+=array(i)(j)
    return result

for i in range(T):    
    bfs() # 확산
    air_work()


print(check())