깡뇽

[백준] 17144번 미세먼지 안녕! 파이썬 본문

Algorithm/BAEKJOON

[백준] 17144번 미세먼지 안녕! 파이썬

깡뇽 2022. 10. 5. 23:59
반응형

(r, c) : r행 c열 

공기청정기는 2행을 차지하며, 항상 1번 열에 설치.

공기청정기가 없는 칸 (r, c)에는 미세먼지가 Ar,c 만큼 존재.

 

<변화>

  1. 미세먼지가 확산된다. 확산은 미세먼지가 있는 모든 칸에서 동시에 일어난다.
    • (r, c)에 있는 미세먼지는 인접한 네 방향으로 확산된다.
    • 인접한 방향에 공기청정기가 있거나, 칸이 없으면 그 방향으로는 확산이 일어나지 않는다.
    • 확산되는 양은 Ar,c/5이고 소수점은 버린다.
    • (r, c)에 남은 미세먼지의 양은 Ar,c - (Ar,c/5)×(확산된 방향의 개수) 이다.
  2. 공기청정기가 작동한다.
    • 공기청정기에서는 바람이 나온다.
    • 위쪽 공기청정기의 바람은 반시계방향으로 순환하고, 아래쪽 공기청정기의 바람은 시계방향으로 순환한다.
    • 바람이 불면 미세먼지가 바람의 방향대로 모두 한 칸씩 이동한다.
    • 공기청정기에서 부는 바람은 미세먼지가 없는 바람이고, 공기청정기로 들어간 미세먼지는 모두 정화된다.

 

- 입력

1줄 : R, C, T 

2~R줄 : Ar,c (공기청정기가 설치된 곳은 -1이며, 가장 윗 행 아랫 행과 두칸이상 떨어짐 / 나머지는 미세먼지의 양)

 

- 출력

T초가 지난 후 방에 남아있는 미세먼지의 양

 

 

17144번 미세먼지 안녕!

고민) 처음에 공기청정기의 위치를 search_machine함수로 찾는다. 미세먼지가 상하좌우 확산되는 함수 difuse와 공기청정기로 인해 순환하는 함수 clean을 만들고, 공기청정기의 위치와 처음 미세먼지 값이 들어있는 2중리스트 a를 매개변수로 받는다. difuse함수에서 dx와 dy를 활용해 a를 벗어나거나 공기청정기가 있는 위치 외에 mist값(미세먼지 dust를 5로 나누어 확산되는 수치)를 더해준다. 미세먼지 회전에서 바깥만 큐로 넣어서 이동 시킨 후에 다시 기존 a에 넣어주려고 했다. 흠..

 

from collections import deque

r, c, t = map(int, input().split())

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

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def diffuse(cleanser):
  cnt = 0
  nx, ny = 0, 0
  dust = a[nx][ny]
  mist = dust // 5
  
  for i in range(4):
    
    nx = nx + dx[i]
    ny = ny + dy[i]
    if nx < 0 or nx >= c or ny < 0 or ny >= r:
      cnt += 1
      continue

    if nx == cleanser and ny == 0:
      continue
      
    a[ny-dx[i]][ny-dy[i]] = dust-(mist*(4-cnt))
    a[nx][ny] += mist

  return a

def search_machine(arr):
  for i in range(r):
    if -1 == arr[i][0]:
      return i
    else:
      pass

def clean(arr, cleanser):
  queue_up = deque()
  queue_down = deque()
  
  for n in range(cleanser+1):
    for m in range(c):
      if n == 0 or m == 0:
        queue_up.append(arr[n][m])

  for n in range(cleanser+1, r):
    for m in range(c):
      if n == 0 or m == 0:
        queue_down.append(arr[n][m])
    ??
  

def solution(cleanser):
  for _ in range(t):
    after_diffuse = diffuse(cleanser)
    clean(after_diffuse, cleanser)

  answer = 0
  for line in a:
    answer += sum(line)
  
  print(answer + 2)

cleanser_loc = search_machine(a)
solution(cleanser_loc)

 

해답) 공기청정기의 위치를 top과 bottom으로 받고, diffuse함수로 상하좌우 확산을 구현하고 clean_top과 clean_bottom으로 공기청정기 순환을 구현했다. 내가 생각했던 걸 훨씬 간단하게 구현하신 듯 하다.

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

#공기청정기 위치 찾기
for i in range(r):
    if graph[i][0] == -1:
        top = i
        bottom = i + 1
        break

#상하좌우 확산
def diffuse():
    dx, dy = (-1, 1, 0, 0), (0, 0, -1, 1)
    diffused = [[0] * c for _ in range(r)]

    for x in range(r):
        for y in range(c):
            if graph[x][y] == 0 or graph[x][y] == -1:
                continue

            dust = graph[x][y] // 5

            for i in range(4):
                nx, ny = x + dx[i], y + dy[i]

                if 0 <= nx < r and 0 <= ny < c and graph[nx][ny] != -1:
                    diffused[nx][ny] += dust
                    diffused[x][y] -= dust

    for i in range(r):
        for j in range(c):
            graph[i][j] += diffused[i][j]

#공기청정기 위쪽 순환
def clean_top():
    dx, dy = (0, -1, 0, 1), (1, 0, -1, 0)
    x, y, d = top, 1, 0
    prev = 0

    while True:
        nx, ny = x + dx[d], y + dy[d]

        if x == top and y == 0:
            break
        if not 0 <= nx < r or not 0 <= ny < c:
            d += 1
            continue

        graph[x][y], prev = prev, graph[x][y]
        x, y = nx, ny

#공기청정기 아래쪽 순환
def clean_bottom():
    dx, dy = (0, 1, 0, -1), (1, 0, -1, 0)
    x, y, d = bottom, 1, 0
    prev = 0

    while True:
        nx, ny = x + dx[d], y + dy[d]

        if x == bottom and y == 0:
            break
        if not 0 <= nx < r or not 0 <= ny < c:
            d += 1
            continue

        graph[x][y], prev = prev, graph[x][y]
        x, y = nx, ny

for _ in range(t):
    diffuse()
    clean_top()
    clean_bottom()

print(sum(map(sum, graph)) + 2)

 

 

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

 

17144번: 미세먼지 안녕!

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

www.acmicpc.net

참고 : https://velog.io/@ms269/%EB%B0%B1%EC%A4%80-17144-%EB%AF%B8%EC%84%B8%EB%A8%BC%EC%A7%80-%EC%95%88%EB%85%95-%ED%8C%8C%EC%9D%B4%EC%8D%AC-Python

 

[백준] #17144 - 미세먼지 안녕! (파이썬, Python)

[백준] #17144 - 미세먼지 안녕!

velog.io

 

반응형