본문 바로가기

너와!나의!알고!리즘!/백준

[백준 #17144, Python] 미세먼지안녕!

[문제]

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사과는 뛰어난 코딩 실력을 이용해 각 칸 (r, c)에 있는 미세먼지의 양을 실시간으로 모니터링하는 시스템을 개발했다. (r, c)는 r행 c열을 의미한다.

공기청정기는 항상 1번 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼지가 있고, (r, c)에 있는 미세먼지의 양은 Ar,c이다.

1초 동안 아래 적힌 일이 순서대로 일어난다.

  1. 미세먼지가 확산된다. 확산은 미세먼지가 있는 모든 칸에서 동시에 일어난다.
    • (r, c)에 있는 미세먼지는 인접한 네 방향으로 확산된다.
    • 인접한 방향에 공기청정기가 있거나, 칸이 없으면 그 방향으로는 확산이 일어나지 않는다.
    • 확산되는 양은 Ar,c/5이고 소수점은 버린다.
    • (r, c)에 남은 미세먼지의 양은 Ar,c - (Ar,c/5)×(확산된 방향의 개수) 이다.
  2. 공기청정기가 작동한다.
    • 공기청정기에서는 바람이 나온다.
    • 위쪽 공기청정기의 바람은 반시계방향으로 순환하고, 아래쪽 공기청정기의 바람은 시계방향으로 순환한다.
    • 바람이 불면 미세먼지가 바람의 방향대로 모두 한 칸씩 이동한다.
    • 공기청정기에서 부는 바람은 미세먼지가 없는 바람이고, 공기청정기로 들어간 미세먼지는 모두 정화된다.

[풀이]

지난번 a형에서 풀었던 삼국지랑,,고냥 똑같은 문제다,, 그런데 이제 좀 복잡함을 곁들인,,,아닌가? 삼국지가 더 복잡했던 거 같기도,, 공기 순환과정에서 반복되는 코드가 너무 많아서 지저분하답,,, Python으로는 통과조차 안되는 너란 코드~ 

while문 처리에서 많이 애를 먹었지만,, 해결,,

 

from sys import stdin
from collections import deque
def spread():
    dusty_room = deque() #미세먼지가 있는방들
    spread_room = deque()
    for r in range(R):
        for c in range(C):
            if room[r][c] != -1 and room[r][c] != 0:
                dusty_room.append((r,c))
    while dusty_room:
        for j in range(len(dusty_room)):
            r,c = dusty_room[j]
            cnt = 0 #퍼트린 방의 개수
            for i in range(4):
                nr = r + dr[i]
                nc = c + dc[i]
                if 0<=nr<R and 0<=nc<C:
                    if room[nr][nc] != -1:
                        dust = room[r][c] // 5
                        spread_room.append((nr,nc,dust))
                        cnt += 1
            spread_room.append((r,c,-(room[r][c]//5*cnt)))
        return spread_room

def air_cleaner():
    moving = []
    idx = 0
    i,j = cleaner[idx]
    nr,nc = i,j+1
    moving.append((nr,nc,0))
    #위에있을때
    while True:
        if nr == i and nc != j:
            while 0<nc < C-1:
                moving.append((nr,nc+1,room[nr][nc]))
                nc += 1
            if nc == C-1:
                moving.append((nr-1,nc,room[nr][nc]))
                nr -= 1
        elif 0<nr<i and nc== C-1:
            while nr > 0:
                moving.append((nr-1,nc,room[nr][nc]))
                nr -= 1
        elif nr == 0:
            while nc > 0:
                moving.append((nr,nc-1,room[nr][nc]))
                nc -= 1
            if nc == 0:
                moving.append((nr+1,nc,room[nr][nc]))
                nr += 1
        elif 0<nr<i and nc == 0:
            while nr < i-1:
                moving.append((nr+1,nc,room[nr][nc]))
                nr += 1
            if nr == i-1:
                nr += 1
        elif nr == i and nc == j:
            break
    #아래 있은 녀석
    idx = 1
    i,j = cleaner[idx]
    nr,nc = i,j+1
    moving.append((nr,nc,0))
    while True:
        if nr == i and nc != j:
            while 0<nc < C-1:
                moving.append((nr,nc+1,room[nr][nc]))
                nc += 1
            if nc == C-1:
                moving.append((nr+1,nc,room[nr][nc]))
                nr += 1
        elif i<nr<R-1 and nc== C-1:
            while nr < R-1:
                moving.append((nr+1,nc,room[nr][nc]))
                nr += 1
        elif nr == R-1:
            while nc > 0:
                moving.append((nr,nc-1,room[nr][nc]))
                nc -= 1
            if nc == 0:
                moving.append((nr-1,nc,room[nr][nc]))
                nr -= 1
        elif i<nr<R-1 and nc == 0:
            while nr > i+1:
                moving.append((nr-1,nc,room[nr][nc]))
                nr -= 1
            if nr == i + 1:
                nr -= 1
        elif nr == i and nc == j:
            break

    return moving

R,C,T = map(int,stdin.readline().split())
room = [list(map(int,stdin.readline().split())) for _ in range(R)]
dr = [-1,1,0,0]
dc = [0,0,-1,1]
time = 0
cleaner = [] #공기 청정기의 위치치
for r in range(R):
    for c in range(C):
        if room[r][c] == -1:
            cleaner.append((r,c))
while time < T:
    arr = spread()
    for p in arr:
        i,j,a = p
        room[i][j] += a
    moving = air_cleaner()
    for n in moving:
        nr,nc,na = n
        room[nr][nc] = na
    time += 1
answer = sum(sum(room,[]))
answer += 2
print(answer)