[BOJ] 7576. 토마토

Jimeaning·2023년 5월 15일
1

코딩테스트

목록 보기
95/143

Python3

문제

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

키워드

  • 그래프

문제 풀이

문제 요구사항

  • 토마토는 격자 모양 상자의 칸에 하나씩 넣어서 보관한다.
  • 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다.
  • 하나의 토마토의 인접한 곳은 왼쪽, 오른쪽, 앞, 뒤 네 방향에 있는 토마토를 의미한다. 대각선 방향에 있는 토마토들에게는 영향을 주지 못하며, 토마토가 혼자 저절로 익는 경우는 없다고 가정한다.
    => Connected Component
  • 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지, 그 최소 일수를 알고 싶어 한다.
    => 며칠이 지나면 토마토들이 모두 익는지, 그 최소 일수를 구하는 프로그램
  • 단, 상자의 일부 칸에는 토마토가 들어있지 않을 수도 있다.
  • 하나의 줄에는 상자 가로줄에 들어있는 토마토의 상태가 M개의 정수로 주어진다.
    => 인접 행렬 adjMatrix 사용
  • 정수 1은 익은 토마토, 정수 0은 익지 않은 토마토, 정수 -1은 토마토가 들어있지 않은 칸을 나타낸다.

변수 및 함수 설명

  • n : 상자의 세로 칸의 수
  • m : 상자의 가로 칸의 수 (단, 2 ≤ M,N ≤ 1,000)
  • cnt : 토마토가 다 익는데 걸리는 시간
  • dy, dx : 상하좌우 이동
  • visited : 방문 처리하는 2차원 배열 (0으로 초기화)
  • adjMatrix : 토마토 배열을 저장하는 2차원 배열
  • bfsQueue : bfs를 수행할 큐
  • currentLocation : 현재 위치
  • curY, curX : 현재 y, x 좌표
  • ny, nx : 다음으로 이동할 y, x 좌표

풀이

(입력 및 선언)

  • 상자의 세로와 가로 칸의 수를 입력받는다
  • 토마토의 위치를 입력 받는다

(bfs 함수)

  • 큐에 원소가 있을 때까지 반복한다
  • bfsQueue의 첫 번째 원소를 꺼내 currentLocation 변수에 저장한다.
  • currentLocation 튜플의 y, x를 각각 curY, curX에 저장한다.
  • 4번(상하좌우) 반복한다.
  • 다음으로 이동할 좌표는 현재 좌표에 dy[i], dx[i]를 더한 값이다.
  • 만약 상자 칸을 벗어나면 continue로 건너뛴다.
  • 만약 토마토가 -1이라면 건너뛴다.
  • 만약 방문처리가 이미 된 곳이라면 건너뛴다.
  • 세 가지 조건 모두 해당되지 않으면, 방문처리를 하고 큐에 해당 튜플을 넣는다.
  • 익히는데 필요한 시간의 최대값을 넣는다. (최소 일수를 구하라고 했지만 최대값을 넣는 이유는 토마토가 다 익어야 하기 때문이다)

(토마토를 찾자)

  • 토마토 map(adjMatrix)을 다 돌면서 토마토가 있는 곳(1)과 방문하지 않은 곳을 찾는다
  • 만약 찾으면 큐에 해당 튜플을 넣고, 방문 처리를 해준다.
  • 모든 토마토를 다 찾고 난 후에 bfs함수를 실행한다
    (토마토를 찾을 때마다 호출하게 되면 최소값이 아니게 된다.)

(토마토가 다 익을 수 없는 경우 처리)

  • 만약 방문도 안 했고, 토마토가 익지 않은 곳이 하나라도 있다면
  • -1을 출력하고 실행문을 종료한다.

(최종 출력)

  • 익는데 필요한 시간인 cnt를 출력한다

최종 코드

from collections import deque

m, n = map(int, input().split())

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

adjMatrix = []
visited = [[0 for _ in range(m)] for _ in range(n)]
bfsQueue = deque([])
cnt = 0

for _ in range(n) :
    adjMatrix.append(list(map(int, input().split())))

# bfs - queue
def bfs() :
    global cnt
    while bfsQueue :
        currentLocation = bfsQueue.popleft()
        curY = currentLocation[0]
        curX = currentLocation[1]
        for i in range(4) :
            ny = curY + dy[i]
            nx = curX + dx[i]
            if ny < 0 or nx < 0 or ny >= n or nx >= m :
                continue
            if adjMatrix[ny][nx] == -1 :
                continue
            if visited[ny][nx] != 0 :
                continue
            visited[ny][nx] = visited[curY][curX] + 1
            cnt = max(cnt, visited[curY][curX])
            bfsQueue.append((ny, nx))

# bfs - visited, queue, bfs()
for i in range(n) :
    for j in range(m) :
        if adjMatrix[i][j] == 1 and visited[i][j] == 0 :
            bfsQueue.append((i, j))
            visited[i][j] = 1
bfs()

for i in range(n) :
    for j in range(m) :
        if visited[i][j] == 0 and adjMatrix[i][j] == 0 :
            print(-1)
            exit()
print(cnt)
profile
I mean

0개의 댓글