https://www.acmicpc.net/problem/17144
파이썬 객체지향으로 푸는 공기청정기 시뮬레이션 문제
1. 문제 구조 요약
방은 R×C 격자로 이루어져 있고, 공기청정기가 설치된 두 칸을 기준으로 미세먼지가 확산되고 정화되는 시뮬레이션이 T초 동안 반복된다.
2. 객체지향 접근 이유
- 격자 상태를 멤버 변수로 유지
- 확산, 정화 기능을 메서드로 모듈화
- 공기청정기의 위치를 캡슐화하여 코드 안정성 확보
3. Room 클래스 구조
3.1 생성자 및 공기청정기 위치 확인
class Room:
def __init__(self, R, C, T, grid):
self.R, self.C, self.T = R, C, T
self.grid = grid
self.cleaner = self._find_cleaner()
def _find_cleaner(self):
for r in range(self.R):
if self.grid[r][0] == -1:
return (r, r + 1)
3.2 시뮬레이션 수행
def simulate(self):
for _ in range(self.T):
self._spread()
self._purify()
3.3 미세먼지 확산 구현
def _spread(self):
temp = [[0] * self.C for _ in range(self.R)]
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for r in range(self.R):
for c in range(self.C):
if self.grid[r][c] > 0:
amount = self.grid[r][c] // 5
cnt = 0
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < self.R and 0 <= nc < self.C and self.grid[nr][nc] != -1:
temp[nr][nc] += amount
cnt += 1
self.grid[r][c] -= amount * cnt
for r in range(self.R):
for c in range(self.C):
self.grid[r][c] += temp[r][c]
3.4 공기청정기 작동
def _purify(self):
upper, lower = self.cleaner
self._circulate_upper(upper)
self._circulate_lower(lower)
3.5 위쪽 공기청정기 (반시계)
def _circulate_upper(self, r):
for i in range(r-1, 0, -1):
self.grid[i][0] = self.grid[i-1][0]
for i in range(self.C-1):
self.grid[0][i] = self.grid[0][i+1]
for i in range(r):
self.grid[i][self.C-1] = self.grid[i+1][self.C-1]
for i in range(self.C-1, 1, -1):
self.grid[r][i] = self.grid[r][i-1]
self.grid[r][1] = 0
3.6 아래쪽 공기청정기 (시계)
def _circulate_lower(self, r):
for i in range(r+1, self.R-1):
self.grid[i][0] = self.grid[i+1][0]
for i in range(self.C-1):
self.grid[self.R-1][i] = self.grid[self.R-1][i+1]
for i in range(self.R-1, r, -1):
self.grid[i][self.C-1] = self.grid[i-1][self.C-1]
for i in range(self.C-1, 1, -1):
self.grid[r][i] = self.grid[r][i-1]
self.grid[r][1] = 0
3.7 남은 미세먼지 합산
def dust_total(self):
return sum(sum(cell for cell in row if cell > 0) for row in self.grid)
4. 전체 코드
class Room:
def __init__(self, R, C, T, grid):
self.R, self.C, self.T = R, C, T
self.grid = grid
self.cleaner = self._find_cleaner()
def _find_cleaner(self):
for r in range(self.R):
if self.grid[r][0] == -1:
return (r, r + 1)
def simulate(self):
for _ in range(self.T):
self._spread()
self._purify()
def _spread(self):
temp = [[0] * self.C for _ in range(self.R)]
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for r in range(self.R):
for c in range(self.C):
if self.grid[r][c] > 0:
amount = self.grid[r][c] // 5
cnt = 0
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < self.R and 0 <= nc < self.C and self.grid[nr][nc] != -1:
temp[nr][nc] += amount
cnt += 1
self.grid[r][c] -= amount * cnt
for r in range(self.R):
for c in range(self.C):
self.grid[r][c] += temp[r][c]
def _purify(self):
upper, lower = self.cleaner
self._circulate_upper(upper)
self._circulate_lower(lower)
def _circulate_upper(self, r):
for i in range(r-1, 0, -1):
self.grid[i][0] = self.grid[i-1][0]
for i in range(self.C-1):
self.grid[0][i] = self.grid[0][i+1]
for i in range(r):
self.grid[i][self.C-1] = self.grid[i+1][self.C-1]
for i in range(self.C-1, 1, -1):
self.grid[r][i] = self.grid[r][i-1]
self.grid[r][1] = 0
def _circulate_lower(self, r):
for i in range(r+1, self.R-1):
self.grid[i][0] = self.grid[i+1][0]
for i in range(self.C-1):
self.grid[self.R-1][i] = self.grid[self.R-1][i+1]
for i in range(self.R-1, r, -1):
self.grid[i][self.C-1] = self.grid[i-1][self.C-1]
for i in range(self.C-1, 1, -1):
self.grid[r][i] = self.grid[r][i-1]
self.grid[r][1] = 0
def dust_total(self):
return sum(sum(cell for cell in row if cell > 0) for row in self.grid)
if __name__ == "__main__":
import sys
input = sys.stdin.read
data = input().split()
R, C, T = map(int, data[:3])
grid = [list(map(int, data[i*C+3:(i+1)*C+3])) for i in range(R)]
room = Room(R, C, T, grid)
room.simulate()
print(room.dust_total())
5. 결론
이 문제는 격자 상태를 지속적으로 변경하며 시뮬레이션하는 문제로, 객체지향 프로그래밍(OOP)을 적용했을 때 구조적으로 분명하고 유지보수도 쉬워진다. 각 기능을 메서드로 분리하고 상태를 캡슐화함으로써 복잡도를 줄이고 디버깅과 기능 확장이 수월해진다.

'Tech > Coding' 카테고리의 다른 글
| 도깨비말(Pig Latin) (0) | 2025.06.23 |
|---|---|
| 색칠 공부 (0) | 2025.06.22 |
| 회문 끝말잇기 (0) | 2025.06.02 |
| SciComLove (2023) (0) | 2025.05.27 |
| ROPE 자료구조: 구조와 동작 원리(Python 예제) (0) | 2025.05.24 |