https://www.acmicpc.net/problem/7576
7576번: 토마토
첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토
www.acmicpc.net
백준의 BFS 문제의 정석!!!!
🐾 20221024
💻 c++로는 여러번 풀었지만 파이썬으로는 처음 풀어본다.
<코드>
from collections import deque
dx = [1,0,-1,0]
dy = [0,1,0,-1]
m,n = map(int, input().split())
arr = [list(map(int,input().split()))for _ in range(n)]
queue = deque()
for i in range(n) :
for j in range(m) :
if arr[i][j]==1 :
queue.append([i,j])
def bfs() :
while queue:
x,y =queue.popleft()
for i in range(4) :
nx ,ny = x+dx[i], y +dy[i]
if 0<=nx<n and 0<=ny<m and arr[nx][ny]==0 :
arr[nx][ny] = arr[x][y]+1
queue.append([nx,ny])
bfs()
result = 0
for i in arr :
for j in i :
if j == 0 :
print(-1)
exit(0)
result = max(result,max(i))
print(result-1)
여기서 새롭게 알게된 코드 2부분이 있다.
1. 띄어쓰기로 구분된 이차원리스트를 입력받기
arr = list(map(int, input().split()))
-> 일단 이렇게 띄어쓰기로 구분된 숫자를 입력받아 정수형 리스트로 만들어주는 코드는 알고있었다.
이를 이차원 리스트로 받으려면 이것을 for문을 통해 반복시키고 리스트화 하면된다.
arr =[list(map(int, input().split())) for _ in range(n)]
여기서 for✅_ ✅in 을 띄어쓰기 해주어야한다.
2. 이차원 리스트를 돌면서 0의 여부를 확인하고 가장 큰 값 확인하기
for i in arr :
for j in i :
if j == 0 :
print(-1)
exit(0)
result = max(result,max(i))
이해를 돕기위해 그림을 그려보았다.
arr는 n개의 리스트로 이루어져있다.
그 각각의 리스트가 i 가 되고
i 에서 각각의 문자가 j 가 되어 j에 0이 있는지 확인하고
하나의 i가 끝날때 max를 이용해 가장 큰 수를 구한다.
🔑 그래서 어떻게 푸는데(정리)?
1. 2차원 리스트를 잘 만든다.
2. 2중 for문을 통해 1이 들어온 좌표를 덱에 넣는다.
3. dx , dy를 이용해 다음 x,y좌표를 구하고 범위에 맞는지, 방문 한적이 있는지 여부를 확인한다.
4. 확인 결과 내부에 있으며, 방문한적이 없다면 덱에 넣는다.
5. 덱이 빌 때까지 계속 반복한다.
6. 2차원 리스트를 돌면서 0이 있다면 -1을 출력하고 아니라면 최댓값을 구해 -1하여 출력한다.
(토마토가 처음 1이였고 여기에서 1씩 증가시켰으므로 )
이제 이 정도는 그냥 풀수있다ㅎㅎ
복습 코드 :
from collections import deque
dx = [0,1,0,-1]
dy = [1,0,-1,0]
if __name__=="__main__" :
m,n = map(int,input().split())
mp = [list(map(int,input().split())) for _ in range(n)]
vis = [[-1]*m for _ in range(n)]
q = deque()
# 익은 토마토를 덱에 넣기
for i in range(n) :
for j in range(m) :
if mp[i][j] == 1 :
q.append([i,j])
vis[i][j] = 0
# 토마토 전염
while q :
x,y = q.popleft()
for dir in range(4) :
nx,ny = dx[dir] + x , dy[dir] + y
if 0<=nx<n and 0<=ny<m and mp[nx][ny] == 0 and vis[nx][ny] == -1:
q.append([nx,ny])
vis[nx][ny] = vis[x][y] +1
# 만약 토마토가 비어있지 않은데 방문을 안했다?(익지 않았다.)
# 그러면 안익은 토마토가 있는 것이므로 -1을 출력한 후 끝낸다.
for i in range(n) :
for j in range(m) :
if mp[i][j] != -1 and vis[i][j] == -1 :
print(-1)
exit(0)
print(max(sum(vis,[])))
[참고]
[백준] 7576: 토마토 (파이썬 / 해설포함)
7576번: 토마토 첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에
jae04099.tistory.com
'알고리즘 > 백준 문제풀이' 카테고리의 다른 글
[Python/BOJ] 백준 14442 벽 부수고 이동하기2(BFS)-시간초과에서 삽질하다가 AC (3) | 2022.01.14 |
---|---|
[Python/BOJ] 백준 2206 벽 부수고 이동하기(BFS) (0) | 2022.01.13 |
[Python/BOJ] 백준 1697 숨바꼭질 (dfs) (0) | 2022.01.10 |
[Python/BOJ] 백준 2644 촌수계산 (bfs) (0) | 2022.01.10 |
[Python/BOJ] 백준 2606 바이러스 (dfs) (0) | 2021.12.27 |