이코테 149p
제한
입력
출력
예시
N * M 크기의 얼음 틀이 있다.
구멍이 뚫린 부분은 0, 칸막이가 있는 부분은 이다.
00110
00011
11111
00000
일 경우 아이스크림이 3개 생성된다.
- 행렬형태를 그래프로 바꾸어 생각하자.
- pytohnic한 상하좌우 움직이는 법에 익숙해지자
- 연결되어있는 덩어리 찾는 방법 = DFS/BFS로 연결된 부분'만' 전부 탐색하기
를 생각해내기
개인적으로는 DFS/BFS = 찾는 '탐색' 으로만 집중했는데
탐색이 가능한 조건은 '그래프(덩어리)'안에서 '연결되어있는 경로로만' 탐색이 가능하다는 점을 캐치하고 나서 왜 DFS/BFS가 쓰여야하는지를 인지하게 됐다.
'어떻게 덩어리를 찾을 수 있지?' -> '덩어리 = 한개의 그래프'일때, DFS/BFS를 통해 모든 연결된 node를 탐색하여 덩어리를 구분 할 수 있겠군
의 생각의 흐름이 바람직할 것 같다.
n, m = map(int, input().split())
graph = []
for i in range (n) :
graph.append(list(map(int, input())))
# DFS
def DFS(x, y) :
stack = []
# 주어진 범위를 벗어나는 경우 즉시 종료
if x <= -1 or x >= n or y <= -1 or y >= m :
return False
# 현재 노드를 아직 방문하지 않았다면
if graph[x][y] == 0 :
# 해당 노드 방문 처리
# 상 하 좌 우 위치도 모두 재귀적으로 호출
dfs(x-1, y)
dfs(x, y-1)
dfs(x+1, y)
dfs(x, y+1)
return True
return False
# 모든 노드에 대하여 음료수 채우기
result = 0
for i in range(n) :
for j in range(m) :
# 현재 위치에서 DFS 수행
if DFS(i, j) == True :
result += 1
print(result)
이코테 152p
- 시작지점부터 가까운 노드부터 차례로 모든 노드를 탐색한다.
= "가까운" 노드부터 탐색하는 것이므로, 처음으로 조건을 만족하는 때가 "최소" 임을 보장할 수 있다!
위의 DFS와 마찬가지로,
BFS는 탐색알고리즘인데 왜 여기에 적용되어야하는가를 생각할 수 있어야한다!
BFS의 특징(이자 구현자체)에서
BFS에서 처음으로 조건을 만족하는 때가, '최소' 임을 보장함을 추론해낼 수 있었으면 좋겠다!
벽은 0이고, 갈 수 있는 길은 1일때, BFS 수행할때마다 ++ 해주면, 최종 목적지에는 지금까지 움직인 수가 기록된다.
밑의 코드를 보고, 어떻게 카운트 되는지 인지하자!
from collections import deque
# N, M 공백으로 구분하여 입력받기
n, m = map(int, input().split())
# 2차원 리스트의 맵 정보 입력받기
graph = []
for i in range (n) :
graph.append(list(map(int, input())))
# 이동할 네 방향 정의
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# BFS 코드 구현
def bfs(x,y) :
# queue 구현을 위해 deque라이브러리 사용
queue = deque()
queue.append((x,y))
# queue가 빌때까지 반복
while queue :
x, y = queue.popleft()
# 현재 위치에서 네 방향으로의 위치 확인
for i in range(4) :
# nx,ny = 갈수도 있는 좌표
nx = x + dx[i]
ny = y + dy[i]
# 미로 찾기 공간을 벗어난 경우 무시
if nx<0 or ny<0 or nx>=n or ny>=m :
continue
# 벽인 경우 무시
if graph[nx][ny] == 0 :
continue
# 해당 노드를 처음 방문하는 경우에만 최단 거리 기록
####################################
# 0이면 벽이어서 못가고, 2면 이미 방문해서 못간다.
if graph[nx][ny] == 1 :
##########################
graph[nx][ny] = graph[x][y] + 1 #1을 더해서, 지금까지 온 만큼을 카운트 한다!!
#########################
queue.append((nx, ny)) # nx, ny가 진짜 가는 좌표가 된다.
# 가장 오른쪽 아래까지의 최단거리 반환
return graph[n-1][m-1]