https://www.acmicpc.net/problem/17144
17144호: 입자상 물질 안녕하세요!
미세먼지를 제거하기 위해 오래된 사과는 공기청정기를 설치하려고 합니다. 공기청정기의 성능을 테스트하기 위해 오래된 사과집을 1×1 셀로 나눈 R×C 크기의 그리드로 표현했습니다. 사용
www.acmicpc.net

솔루션 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())