본문 바로가기
Algorithm/Baekjoon

17144. 미세먼지 안녕 (Python)

by 원만사 2022. 2. 19.
반응형
 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사

www.acmicpc.net

 

풀이

 단순한 구현 문제로 문제에서 주어진 순서대로 코드를 작성하면 된다. 미세먼지가 확산하는 과정을 diffuse() 함수로 만들었고 공기청정기가 작동하는 과정을 cleanAir() 함수로 만들었다.

 

 미세먼지가 있는 좌표를 담아두는 리스트를 만들어서 (행, 열, 미세먼지 수치)와 같은 형태의 튜플로 담아두었다. 이 리스트를 통해서 diffuse() 함수에서 미세먼지를 확산시킨다. cleanAir()에서는 공기청정기가 작동하는 반대방향 순으로 for문을 통해서 각각 미세먼지 수치를 이동시키도록 한다. 

 공기청정기의 작동을 다 마치고나면 좌표 전체를 탐색해서 다시 한 번 미세먼지가 있는 좌표의 값들을 찾아서 리스트에서 담아서 return 해주고 해당 값을 다시 diffuse()로 전달하여 위와 같은 과정을 반복하도록 한다.

 

 과정이 다 끝난 후 미세먼지 좌표 리스트에서 미세먼지 수치들을 다 더하여 출력한다.

 

코드

def isRange(x, y):
    return 0 <= x < R and 0 <= y < C


# 미세먼지 확산 함수 
def diffuse(dusts):
    for (x, y, dust) in dusts:
        diffuseAmount = dust // 5 # 확산되는 양 
        diffuseCount = 0 # 확산된 방향의 개수 

        for (dx, dy) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
            nx = x + dx
            ny = y + dy

            # 범위를 벗어났거나 공기청정기가 있는 위치면 continue
            if not isRange(nx, ny) or board[nx][ny] == -1:
                continue

            board[nx][ny] += diffuseAmount # 확산되는 위치에 확산되는 양 추가 
            diffuseCount += 1 # 확산된 방향의 개수 추가 

        board[x][y] -= diffuseAmount * diffuseCount # 기존 위치의 미세먼지 양 조정


# 공기청정기 작동 함수
def cleanAir():
    # 위쪽
    for r in range(airCleanerUp-1, 0, -1):
        board[r][0] = board[r-1][0]

    for c in range(1, C):
        board[0][c-1] = board[0][c]

    for r in range(airCleanerUp):
        board[r][C-1] = board[r+1][C-1]

    for c in range(C-1, 1, -1):
        board[airCleanerUp][c] = board[airCleanerUp][c-1]
    board[airCleanerUp][1] = 0 # 공기청정기로 들어가서 정화되는 미세먼지 

    # 아래쪽
    for r in range(airCleanerDown+1, R-1):
        board[r][0] = board[r+1][0]

    for c in range(1, C):
        board[R-1][c-1] = board[R-1][c]

    for r in range(R-1, airCleanerDown, -1):
        board[r][C-1] = board[r-1][C-1]

    for c in range(C-1, 0, -1):
        board[airCleanerDown][c] = board[airCleanerDown][c-1]
    board[airCleanerDown][1] = 0 # 공기청정기로 들어가서 정화되는 미세먼지 

    # 맵 전체를 탐색하여 새로운 미세먼지 좌표 리스트를 작성하여 반환한다.
    newDusts = []
    for i in range(R):
        for j in range(C):
            if board[i][j] > 0:
                newDusts.append((i, j, board[i][j]))

    return newDusts


if __name__ == '__main__':
    R, C, T = map(int, input().split())
    board = [] # 맵
    dusts = [] # 미세먼지의 좌표 리스트. (행, 열 미세먼지 수치) 튜플의 형태
    airCleanerDown = 0 # 공기청정기의 아래쪽에 해당하는 행 

    for i in range(R):
        row = list(map(int, input().split()))

        for j in range(C):
            dust = row[j]

            if dust > 0:
                dusts.append((i, j, dust)) # 미세먼지 좌표를 담아준다.
            elif dust == -1:
                airCleanerDown = i # -1을 두 번 만나는데 마지막에 만나는 곳이 공기청정기의 아래쪽에 해당

        board.append(row)
    airCleanerUp = airCleanerDown - 1 # 공기청정기의 아래쪽보다 한 칸 위에 위치하는 곳이 공기청정기의 위쪽에 해당 

    for i in range(T):
        diffuse(dusts) # 1. 미세먼지 확산
        dusts = cleanAir() # 2. 공기청정기 작동 

    totalDust = 0
    for (_, _, dust) in dusts:
        totalDust += dust

    print(totalDust)
반응형

'Algorithm > Baekjoon' 카테고리의 다른 글

2631. 줄세우기 (Python)  (0) 2022.02.23
2212. 센서 (Python)  (0) 2022.02.23
13975. 파일 합치기 3 (Python)  (0) 2022.02.18
1300. K번째 수 (Swift, Python)  (0) 2022.02.14
18428. 감시 피하기 (Python)  (0) 2022.02.12

댓글