[python] 음료수 얼려 먹기

yeco_ob·2023년 2월 1일
0

문제

N * M 크기의 얼음 틀이 있습니다. 구멍이 뚫려있는 부분은 0, 칸막이가 존재하는 부분은 1로 표현됩니다. 구멍이 뚫려있는 부분끼리 상, 하, 좌, 우로 붙어 있는 경우 서로 연결괴어 있는 것으로 간주합니다. 이때 얼음 틀의 모양이 주어졌을 때 생성되는 총 아이스크림의 개수를 구하는 프로그램을 작성하세요.

첫 번째 줄에 얼음 틀의 세로 길이 N, 가로 길이 M을 입력 받습니다. 두 번째 줄부터 N+1 줄까지 얼음 틀의 형태가 주어집니다.
이때 구멍이 뚫려있는 부분은 0, 그렇지 않은 부분은 1입니다.

한 번에 만들 수 있는 아이스크림의 개수를 출력합니다.

해결 방법

이 문제는 DFS, BFS로 해결할 수 있다. 얼음 공간은 서로 연결되어 있는 노드라 생각하자.

모든 노드에 대해 그래프 탐색을 하고 탐색이 가능한 0인 경우 연결된 모든 노드를 방문처리한 후 카운트를 센다.

  1. 특정 지점의 상, 하, 좌, 우를 살피고 0이면서 아직 방문을 하지 않았다면 해당 지점을 방문
  2. 그 자리에서 다시 상, 하, 좌, 우를 살핀 후 방문하는 과정을 반복하면 연결된 지점을 방문
  3. 모든 노드에 대해 위 과정을 반복. 방문하지 않은 지점의 수를 카운트

💡 이게 어떻게 아이스크림의 수를 알 수 있지?

방문한 노드는 1로 바꾸고 다시 방문 X

하나의 노드는 한 번만 탐색한다. 이 탐색이 끝나면 카운트가 된다. 그래서 만들 수 있는 아이스크림의 수를 구할 수 있는 것이다. 이 점을 이해하는 게 중요한데.. 역시 세상에 쉬운 거 하나 없네.. ¯(°_o)/¯

제출

def dfs(x,y):
  #주어진 공간을 벗어나면 종료
  if x <= -1 or x >= n or y <= -1 or y >= m:
    return False
  #현재 노드를 방문하지 않았다면
  if graph[x][y] == 0:
    #방문 처리
    graph[x][y] = 1
    #상, 하, 좌, 우 노드 재귀 호출
    dfs(x-1, y)
    dfs(x, y-1)
    dfs(x+1, y)
    dfs(x, y+1)
    return True
  return False #방문 했던 노드(1)이라면

n, m = map(int, input().split())
graph = []

#얼음틀 정보 입력 받기
for i in range(n):
  graph.append(list(map(int, input())))
  
#모든 노드가 시작점
result = 0
for i in range(n):
  for j in range(m):
    #현재 위치에서 dfs 수행
    if dfs(i, j) == True:
      result += 1 #탐색이 끝나면 카운트

print(result)

(☞゚ヮ゚)☞ 코드를 하나하나 뜯어서 봅시다.

👉 n, m = map(int, input().split())
👉 graph = []

n, m, 2차원 그래프를 담을 리스트를 입력 받고 선언한다.

👉 for i in range(n):
👉 graph.append(list(map(int, input())))

반복문으로 2차원 리스트를 만들어준다. 얼음 틀 상태를 0, 1로 입력 받으며 정수형으로 변경하기

👉 for i in range(n):
👉 for j in range(m):
👉 if dfs(i, j) == True:
👉 result += 1

n, m 이중 반복문으로 모든 노드를 시작점으로 하는 dfs 함수를 실행한다. 이때 탐색이 자아알 끝나면 카운트

👉 def dfs(x,y):

함수를 만들자

👉 if x <= -1 or x >= n or y <= -1 or y >= m:
👉 return False

얼음틀 크기를 넘어가면 False

👉 if graph[x][y] == 0:
👉 graph[x][y] = 1

0은 아직 탐색을 하지 않았다는 뜻이다. 즉 해당 원소가 0이라면 1로 바꿔주면서 방문 처리한다. 그리고

👉 dfs(x-1, y)
👉 dfs(x, y-1)
👉 dfs(x+1, y)
👉 dfs(x, y+1)
👉 return True

여기서 재귀 호출을 한다. 상 하 좌 우 모든 원소를 탐색하도록 한다. 이게 끝나면 True를 반환!

if dfs(i, j) == True:
      result += 1

그럼 이제 result 가 +1 되고 다음 노드부터 다시 탐색을 시작한다.

0개의 댓글