728x90

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

 

7576번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토

www.acmicpc.net

 

 

문제)

 

 

 

해설)

이 문제는 당연히 bfs로 풀어야지!! 하면서 좀 헤맸다..ㅎㅎ

두 가지 방식으로 했는데, 코드는 두 번째가 조금 더 깔끔한 것 같다.

 

 

 

풀이 1)

from collections import deque

def bfs(tomato):
    global box
    dx = [0, 0, -1, 1]
    dy = [1, -1, 0, 0]
    count = 0
    while tomato:
        second = []
        t_li = tomato.popleft()
        for t_mem in t_li:
            x, y = t_mem[0], t_mem[1]
            for i in range(4):
                nx = x + dx[i]
                ny = y + dy[i]
                if 0 <= nx < n and 0 <= ny < m:
                    if box[nx][ny] == 0:
                        second.append([nx, ny])
                        box[nx][ny] = 1
                    else:
                        continue
        if second != []:
            tomato.append(second)
        count += 1
    return count - 1

m, n = map(int, input().split()) # m: col, n: row
box = []
tomato = deque()
for i in range(n):
    box.append(list(map(int, input().split())))

first = []
for i in range(n):
    for j in range(m):
        if box[i][j] == 1:
            first.append([i, j])
tomato.append(first)


day = bfs(tomato)
for i in range(n):
    for j in range(m):
        if box[i][j] == 0:
            print(-1)
            exit(0)
print(day)

bfs 함수 내에서 며칠이나 걸렸는지 반환해주려고 이 코드를 짜게 되었다.

한 박스에 토마토가 여러 개일 경우 동시에 토마토가 있는 좌표의 옆 토마토들이 익는다.

따라서 하루 단위로 익을 토마토(box에서 0인 애들) list(first, second)를 만들어 저장하고, 그것을 tomato라는 queue에 저장하는 방식으로 구현했다.

 

tomato에서 하나를 뽑으면 그 list에 해당하는 좌표를 순회하고, 해당 list에 저장된 좌표를 모두 돌면 하루가 늘어나는 방식이다.

하지만 여기에는 처음에 토마토가 있던 위치도 하루가 지난 것으로 치는 방식이기에 1을 뺀 값을 반환한다.

 

bfs가 모두 끝나면 혹시 토마토가 익지 않은 경우가 있을 수 있기 때문에 확인해준다.

여기에서 익지 않은 토마토가 있을 경우 -1을 출력하고 exit 하여 끝낸다.

그렇지 않다면 bfs 결과를 출력해준다.

 

 

 

풀이 2)

from collections import deque

def bfs(tomato):
    global box
    dx = [0, 0, -1, 1]
    dy = [1, -1, 0, 0]
    while tomato:
        x, y = tomato.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if box[nx][ny] == 0:
                    tomato.append([nx, ny])
                    box[nx][ny] = box[x][y] + 1
                else:
                    continue


m, n = map(int, input().split()) # m: col, n: row
box = []
tomato = deque()
for i in range(n):
    box.append(list(map(int, input().split())))

for i in range(n):
    for j in range(m):
        if box[i][j] == 1:
            tomato.append([i, j])


day = 0
bfs(tomato)
for i in box:
    for j in i:
        if j == 0:
            print(-1)
            exit(0)
    day = max(day, max(i))
print(day - 1)

이 풀이도 똑같이 bfs를 활용했다.

다른 점은 좌표를 차례대로 queue인 tomato에 저장해주고, bfs를 하는 도중 다음 좌표의 box 값이 0이라면 원좌표의 값에 +1을 해주는 방식을 사용했다. 

 

또한 이 방식도 처음 토마토의 위치가 1이어서 하루가 더 더해진 방식이므로 box에 0이 없음을 확인하면 1을 뺀 값을 출력해준다.

 

728x90

'코테 > DFS, BFS' 카테고리의 다른 글

[DFS/BFS] 백준 2606 바이러스(DFS 풀이)  (0) 2022.06.06
[DFS/BFS] 미로 탈출  (0) 2022.06.04
[DFS/BFS] 음료수 얼려 먹기  (0) 2022.06.03
[DFS/BFS] 이론  (0) 2022.04.26

+ Recent posts