[백준] 17144 - 미세먼지 안녕! (G4)

2021. 11. 13. 13:22·알고리즘 (PS)/BOJ
반응형

https://www.acmicpc.net/problem/17144

 

17144번: 미세먼지 안녕!

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

www.acmicpc.net

어렵지 않은 구현 & 시뮬레이션 문제.

꼼꼼하게 구현만 하면 풀 수 있다.

판의 사이즈가 크지 않기 때문에 문제에서 시키는 그대로 알고리즘을 짜서 돌리고,

그 결과값을 출력하면 된다.

 

이 문제를 풀 때는 2가지만 떠올리면 되었다.

 

1. 어떻게 확산을 겹치지 않게 시킬 수 있을지

2. 공기청정기의 확산을 어떻게 구현할 것인지


<1> 어떻게 확산을 겹치지 않게 시킬 수 있을지


가령, 문제의 조건과는 맞지 않지만 단순화해서 5 9 1 과 같은 입력이 있다고 할 때

실제로는 5에서 1의 확산, 9에서 양쪽으로 1의 확산, 1에서 확산이 없어야 한다.

하지만 구현을 잘못하는 경우, 5에서 확산된 결과를 바로 9에 반영해서 10이 되고,

10이된 상태에서 확산을 해서 양쪽으로 2를 보내버리는 문제가 있을 수 있다.

 

나는 단순하게 이 문제를 저장 구조를 분리하여 해결했다.

판사이즈가 50 * 50으로 매우 작은편이기 때문에, 한 칸을 (기존값, 다른 칸에서 확산된 값) 으로 구분하여 저장하고

확산이 모두 끝나면, 다른 값에서 확산된 값을 기존값에 더해주는 식으로 구현했다.


<2> 공기청정기의 확산을 어떻게 구현할 것인지


난 이 부분에서 시간을 조금 썼다. 배열 내에서 로테이션을 구현하는 경험을 많이 해보지 않았기 때문이다.

처음에는 C언어를 처음 배울 때 지겹게 많이 했던 swap을 이용해서 해보는 것을 생각하다가 막혔었다.

그래서 고민끝에 그냥 단순하게 큐를 사용했다.

 

현재 칸의 값을 큐에 push 하고

큐에서 값을 pop 해서( = 이전 칸의 값) 현재 칸에 넣어주고

 

이걸 공기청정기의 흐름방향을 따라가며 반복해주었다.

 


제출 코드


import sys
from collections import deque
input = sys.stdin.readline
dr = [0, 0, 1, -1]
dc = [1, -1, 0, 0]
def PrintBoard():
    for i in range(r):
        print(board[i])
    print()
TEST_MODE = False

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

for i in range(r):
    for j in range(c):
        board[i][j] = [board[i][j], 0]

# 공기청정기 위치 찾기 (위쪽만 알면 아래쪽 자동 결정)
for i in range(r):
    if board[i][0][0] == -1:
        cleaner = i
        break

while t > 0:
    if TEST_MODE:
        print("확산전")
        PrintBoard()
    # 확산
    for i in range(r):
        for j in range(c):
            if board[i][j][0] >= 5:
                value = board[i][j][0] // 5
                for k in range(4):
                    check_i, check_j = i + dr[k], j + dc[k]
                    # 칸이 있고
                    if 0 <= check_i < r and 0 <= check_j < c:
                        # 공기 청정기가 아니면 확산
                        if board[check_i][check_j][0] != -1:
                            board[check_i][check_j][1] += value
                            board[i][j][0] -= value

    # 확산한 결과 합치기
    for i in range(r):
        for j in range(c):
            board[i][j][0] += board[i][j][1]
            board[i][j][1] = 0

    if TEST_MODE:
        print("확산 후")
        PrintBoard()

    # 이동
    # 위 공기청정기
    d = deque()
    d.append(0)
    for j in range(1, c):
        d.append(board[cleaner][j][0])
        board[cleaner][j][0] = d.popleft()

    for i in range(cleaner-1, -1 ,-1):
        d.append(board[i][c-1][0])
        board[i][c-1][0] = d.popleft()

    for j in range(c-2, -1, -1):
        d.append(board[0][j][0])
        board[0][j][0] = d.popleft()

    for i in range(1, cleaner):
        d.append(board[i][0][0])
        board[i][0][0] = d.popleft()

    # 아래 공기 청정기
    d = deque()
    d.append(0)
    for j in range(1, c):
        d.append(board[cleaner+1][j][0])
        board[cleaner+1][j][0] = d.popleft()

    for i in range(cleaner+2, r):
        d.append(board[i][c-1][0])
        board[i][c-1][0] = d.popleft()

    for j in range(c-2, -1, -1):
        d.append(board[r-1][j][0])
        board[r-1][j][0] = d.popleft()

    for i in range(r-2, cleaner+1, -1):
        d.append(board[i][0][0])
        board[i][0][0] = d.popleft()

    if TEST_MODE:
        print("이동 후")
        PrintBoard()

    # 초 카운트
    t -= 1

# 결과 출력
s = 0
for i in range(r):
    for j in range(c):
        s += board[i][j][0]

# 공기 청정기로 -1이 2번 더해진 것 감안한 출력
print(s+2)

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'알고리즘 (PS) > BOJ' 카테고리의 다른 글

[백준] 2473 - 세 용액 (G4)  (0) 2021.11.21
[백준] 17070 - 파이프 옮기기 1 (G5)  (0) 2021.11.14
[백준] 17081 - RPG Extreme (P2)  (2) 2021.08.28
[백준] 20936 - 우선순위 계산기 (P4)  (0) 2021.08.18
[백준] 20129 - 뒤집힌 계산기 (G3)  (2) 2021.08.17
'알고리즘 (PS)/BOJ' 카테고리의 다른 글
  • [백준] 2473 - 세 용액 (G4)
  • [백준] 17070 - 파이프 옮기기 1 (G5)
  • [백준] 17081 - RPG Extreme (P2)
  • [백준] 20936 - 우선순위 계산기 (P4)
에버듀
에버듀
개발은 좋은데 뭘로 개발할까
  • 에버듀
    Blog. 에버듀
    에버듀
  • 전체
    오늘
    어제
    • 분류 전체보기 (615) N
      • 개인 프로젝트 (43)
        • 토이 프로젝트 (3)
        • [2020] 카카오톡 봇 (9)
        • [2021] 코드악보 공유APP (22)
        • [2022] 유튜브 뮤직 클론코딩 (9)
        • [2025] 한글 SQL 데이터베이스 (0)
      • 팀 프로젝트 (22)
        • [2020] 인공지능 숫자야구 (4)
        • [2022] OSAM 온라인 해커톤 (10)
        • [2024] GDSC 프로젝트 트랙 (6)
        • [2025] 큰소리 웹 페이지 (2)
      • CS (335)
        • 자료구조 (19)
        • 어셈블리 (41)
        • 멀티미디어응용수학 (7)
        • 컴퓨터 구조 (29)
        • 알고리즘 분석 (4)
        • 컴퓨터 네트워크 (38)
        • 프로그래밍언어론 (15)
        • HCI 윈도우즈프로그래밍 (26)
        • 기초데이터베이스 (29)
        • 운영체제 (23)
        • 오토마타 (24)
        • 문제해결기법 (11)
        • 블록체인 (22)
        • 소프트웨어공학 (21)
        • 기계학습심화 (12)
        • 컴퓨터그래픽스와 메타버스 (8)
        • 분산시스템특론 (6)
      • 자기계발 (45) N
        • 생각 정리 (23) N
        • 대외활동 (11)
        • 동아리 (7)
        • 자격증 (3)
        • 머니 스터디 (1)
      • 알고리즘 (PS) (107)
        • BOJ (101)
        • Programmers (5)
        • 알고리즘 이모저모 (1)
      • WEB(BE) (8)
        • express.js (1)
        • Spring & Spring Boot (7)
      • WEB(FE) (2)
        • html, css, js (1)
        • React.js (1)
      • Tool & Language (6)
        • Edit Plus (1)
        • Git (1)
        • Python3 (2)
        • Java (2)
      • Infra (12)
        • AWS (1)
        • Oracle Cloud (8)
        • Firebase (2)
        • Network (1)
      • Android (18)
        • Java (6)
        • Flutter (12)
      • Window (2)
        • Visual Studio 없이 WPF (1)
        • MFC (1)
      • 독서 (14)
        • Inside Javascript (7)
        • Database Internals (6)
        • 한 글 후기 (1)
  • 링크

    • github
    • website
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에버듀
[백준] 17144 - 미세먼지 안녕! (G4)
상단으로

티스토리툴바