미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사과는 뛰어난 코딩 실력을 이용해 각 칸 (r, c)에 있는 미세먼지의 양을 실시간으로 모니터링하는 시스템을 개발했다. (r, c)는 r행 c열을 의미한다.
공기청정기는 항상 1번 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼지가 있고, (r, c)에 있는 미세먼지의 양은 Ar,c이다.
1초 동안 아래 적힌 일이 순서대로 일어난다.
미세먼지가 확산된다. 확산은 미세먼지가 있는 모든 칸에서 동시에 일어난다.
공기청정기가 작동한다.
다음은 확산의 예시이다.
왼쪽과 오른쪽에 칸이 없기 때문에, 두 방향으로만 확산이 일어났다.
인접한 네 방향으로 모두 확산이 일어난다.
공기청정기가 있는 칸으로는 확산이 일어나지 않는다.
공기청정기의 바람은 다음과 같은 방향으로 순환한다.
방의 정보가 주어졌을 때, T초가 지난 후 구사과의 방에 남아있는 미세먼지의 양을 구해보자.
첫째 줄에 R, C, T (6 ≤ R, C ≤ 50, 1 ≤ T ≤ 1,000) 가 주어진다.
둘째 줄부터 R개의 줄에 Ar,c (-1 ≤ Ar,c ≤ 1,000)가 주어진다. 공기청정기가 설치된 곳은 Ar,c가 -1이고, 나머지 값은 미세먼지의 양이다. -1은 2번 위아래로 붙어져 있고, 가장 윗 행, 아랫 행과 두 칸이상 떨어져 있다.
첫째 줄에 T초가 지난 후 구사과 방에 남아있는 미세먼지의 양을 출력한다.
7 8 1
0 0 0 0 0 0 0 9
0 0 0 0 3 0 0 8
-1 0 5 0 0 0 22 0
-1 8 0 0 0 0 0 0
0 0 0 0 0 10 43 0
0 0 5 0 15 0 0 0
0 0 40 0 0 0 20 0
188
7 8 2
0 0 0 0 0 0 0 9
0 0 0 0 3 0 0 8
-1 0 5 0 0 0 22 0
-1 8 0 0 0 0 0 0
0 0 0 0 0 10 43 0
0 0 5 0 15 0 0 0
0 0 40 0 0 0 20 0
188
7 8 3
0 0 0 0 0 0 0 9
0 0 0 0 3 0 0 8
-1 0 5 0 0 0 22 0
-1 8 0 0 0 0 0 0
0 0 0 0 0 10 43 0
0 0 5 0 15 0 0 0
0 0 40 0 0 0 20 0
186
주어진 문제를 충실하게👊 구현하여 풀어야 하는 문제입니다.
저는 구현해야 하는 과정을 총 세 부분으로 나누어 보았습니다.
1. 각 칸의 미세먼지가 인접한 네 방향으로 각 1/5씩 확산된다.
➡ 각 칸의 상하좌우 좌표를 확인하고, 존재하는 좌표의 경우 칸의 1/5만큼의 미세먼지를 더해준다. 해당 칸은 확산시킨 미세먼지의 양만큼 빼준다.
2. 공기청정기의 윗부분을 기준으로 바람이 반시계 방향으로 순환한다.
➡ 공기청정기의 윗부분의 좌표를 기준으로 반시계 방향으로 칸들을 계속해서 복사해나간다.
3. 공기청정기의 아랫부분을 기준으로 바람이 시계 방향으로 순환한다.
➡ 공기청정기의 아랫부분의 좌표를 기준으로 시계 방향으로 칸들을 계속해서 복사해나간다.
📍 이 때 주의할 점은, 모든 확산과 순환은 동시다발적으로 일어나기 때문에, 확산과 순환이 진행될 때 업데이트 된 값을 사용하면 안된다는 점입니다.
원래의 리스트를 복사해두고, 업데이트 이전의 값들을 사용해야 합니다.
import copy
import sys
input = sys.stdin.readline
R, C, T = map(int, input().split())
rooms = [[0] * (C + 2)] + \
[[0] + list(map(int, input().split())) + [0] for _ in range(R)] + \
[[0] * (C + 2)] # 1-base 2차원 리스트
machine = [] # 공기청정기의 위치 2개
for i in range(R):
for j in range(C):
if rooms[i][j] == -1:
rooms[i][j] = 0
machine.append((i, j)) # 공기청정기 위치 찾아 저장
pos = [[1, 0], [-1, 0], [0, 1], [0, -1]] # 상하좌우 위치 좌표
for _ in range(T): # T번 반복
new_rooms = copy.deepcopy(rooms) # 기존 리스트 복사
for i in range(1, R + 1): # 미세먼지 확산
for j in range(1, C + 1):
for k in range(4): # 상하좌우에 대하여 확인
nx, ny = i + pos[k][0], j + pos[k][1]
if 0 < nx <= R and 0 < ny <= C and (nx, ny) not in machine:
new_rooms[nx][ny] += rooms[i][j] // 5 # 1/5 추가
new_rooms[i][j] -= (rooms[i][j] // 5) # 1/5 빼기
rooms = copy.deepcopy(new_rooms) # 순환된 상태의 리스트 복사
# 반시계 방향 순환
for i in range(machine[0][0] - 1, 0, -1): #위 -> 아래
rooms[i + 1][1] = new_rooms[i][1]
for i in range(1, C): # 오 -> 왼
rooms[1][i] = new_rooms[1][i + 1]
for i in range(1, machine[0][0]): # 아래 -> 위
rooms[i][C] = new_rooms[i + 1][C]
for i in range(C - 1, 0, -1): # 왼 -> 오
rooms[machine[0][0]][i + 1] = new_rooms[machine[0][0]][i]
# 시계 방향 순환
for i in range(machine[1][0], R): # 아래 -> 위
rooms[i][1] = new_rooms[i + 1][1]
for i in range(1, C): # 오 -> 왼
rooms[R][i] = new_rooms[R][i + 1]
for i in range(R - 1, machine[1][0] - 1, -1): # 위 -> 아래
rooms[i + 1][C] = new_rooms[i][C]
for i in range(C - 1, 0, -1): # 왼 -> 오
rooms[machine[1][0]][i + 1] = new_rooms[machine[1][0]][i]
# 공기청정기 부분 미세먼지 정화
rooms[machine[0][0]][machine[0][1]] = rooms[machine[1][0]][machine[1][1]] = 0
sum_value = 0
for row in rooms:
sum_value += sum(row) # 남은 미세먼지 합 계산
print(sum_value)
- 각 칸의 미세먼지가 인접한 네 방향으로 각 1/5씩 확산된다.
미세먼지가 동시에 확산되기 때문에, 기존의 리스트를 복제하여 값을 참조할 리스트와 값을 바꿔줄 리스트를 구분합니다.
roomsnew_rooms그리고, 각 칸을 확인하며 유효한 좌표(공기 청정기 위치가 아닌 리스트 내의 좌표)에 한해 1/5의 미세먼지를 확산시킵니다.
그리고 해당 칸의 미세먼지는 1/5 줄어듭니다.
- 공기청정기의 윗부분을 기준으로 바람이 반시계 방향으로 순환한다.
순환된 상태의 리스트 값을 사용하되, 이번에도 값을 찹조할 리스트와 값을 실제로 바꿔줄 리스트를 구분해줍니다.
new_roomsrooms그리고 순환 방향에 따라, 값들을 각 방향별로 복제해줍니다.
- 공기청정기의 아랫부분을 기준으로 바람이 시계 방향으로 순환한다.
마찬가지로, 순환 방향에 따라, 값들을 각 방향별로 복제해줍니다.
순환이 끝나면, 공기청정기 위치에 존재하는 미세먼지는 0으로 바꾸어줍니다.
최종적으로 남아있는 미세먼지를 모두 합한 값을 출력하면 됩니다.