Posts [알고리즘] 백준 17144 - 미세먼지 안녕
Post
Cancel

[알고리즘] 백준 17144 - 미세먼지 안녕


문제

17144 - 미세먼지 안녕


접근

단순 구현 문제이다.

크게 나누면 미세먼지가 확산되는 부분과 공기청정기가 작동하여 공기가 순환되는 부분으로 나뉜다.

미세먼지의 확산 같은 경우 전체 칸에서 미세먼지가 동시에 확산된다고 한다.
이 부분은 한칸씩 작업을 하게되면 처리할 수 없다.
나는 배열을 두 개만들어서 원래 미세먼지 배열을 확인하며 확산되는 내용은 새로운 배열에 표시해주었다.
그리고 새로운 배열을 다시 기존 미세먼지 배열로 사용하는 것이다.

두 번째는 공기 순환 부분이다.
이 부분은 위쪽과 아래쪽의 순환 경로가 다르다.
나 같은 경우는 오른쪽, 위쪽, 왼쪽, 아래쪽의 순서로 0,1,2,3의 방향을 지정해서 벽에 막힐 때마다 방향을 전환하게 해주었다.
위쪽 순환의 경우 방향전환은 현재 방향 + 1이다.
4일 경우 0으로 변해야 하므로, (방향 + 1) % 4
아래쪽은 반대로 -1을 해주면 된다.
두 경우를 모두 처리하기 위해 최종적으로 (방향 + 4 + 회전값) % 4 가 된다.
회전값은 위에서 처럼 +1 혹은 -1 이다.

이렇게 하면 시작위치부터 다시 시작위치로 돌아올 때까지 while문 한번이면 된다.

정답은 그냥 배열을 다 더하고, 공기청정기의 값을 빼주면 되므로, +2해준다.


코드

  • 파이썬 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import sys
input = sys.stdin.readline
dx = [1,0,-1,0]
dy = [0,-1,0,1]

def findAirCleaner(board):
    for y, row in enumerate(board):
        for x, item in enumerate(row):
            if item == -1:
                return (x, y), (x, y+1)
def airSpread(board, r, c):
    afterBoard = [[0]*c for _ in range(r)]
    for i in range(r):
        for j in range(c):
            if board[i][j] > 4:
                spreadAmount = board[i][j] // 5
                cnt = 0
                for x, y in zip(dx, dy):
                    nx = j + x
                    ny = i + y
                    if nx < 0 or nx >= c or ny < 0 or ny >= r or board[ny][nx] == -1:
                        continue
                    afterBoard[ny][nx] += spreadAmount
                    cnt += 1
                afterBoard[i][j] += (board[i][j] - (spreadAmount * cnt))
            else:
                afterBoard[i][j] += board[i][j]
    return afterBoard
def workingAirCleaner(board, r, c, startx, starty, nowDirection, rotation):
    nx = startx
    ny = starty

    nowDust = 0
    while True:
        nx = nx + dx[nowDirection]
        ny = ny + dy[nowDirection]
        if nx < 0 or nx >= c or ny < 0 or ny >= r:
            nx = nx - dx[nowDirection]
            ny = ny - dy[nowDirection]
            nowDirection = (nowDirection + 4 + rotation) % 4
            continue

        if nx == startx and ny == starty:
            break

        nxtDust = board[ny][nx]
        board[ny][nx] = nowDust
        nowDust = nxtDust
if __name__ == "__main__":
    r, c, t = map(int, input().split())

    board = [list(map(int, input().split())) for _ in range(r)]

    upWind, downWind = findAirCleaner(board)
    for i in range(t):
        board = airSpread(board, r, c)
        workingAirCleaner(board, r, c, upWind[0], upWind[1], 0, 1)
        workingAirCleaner(board, r, c, downWind[0], downWind[1], 0, -1)
    ans = 0
    for row in board:
        for item in row:
            ans += item
    print(ans+2)


This post is licensed under CC BY 4.0 by the author.

[알고리즘] 백준 15685 - 드래곤 커브

[알고리즘] 백준 5373 - 큐빙