ASHD Dev_Blog

1주차 문제 [DFS/BFS] (1)

이재룡
이재룡Jun 30, 2025
1주차 문제 [DFS/BFS] (1)

[ 1. 음료수 얼려먹기 ]

강의 자료에서 재귀로 너무 간단하게 풀어버려서 Stack으로 풀기 도전

# DFS/BFS 문제 1 : 음료수 얼려먹기 

# N × M 크기의 얼음 틀이 있습니다.
# 얼음 틀의 각 칸은
# 0 : 구멍이 뚫려 있어 물이 들어갈 수 있는 부분
# 1 : 칸막이가 존재하는 부분으로 표시됩니다.
# 구멍(0)이 상·하·좌·우로 서로 맞닿아 있으면 하나의 연결된 영역(덩어리)으로 간주합니다.
# 얼음 틀의 모양이 주어졌을 때, 얼려서 생성되는 아이스크림의 총 개수(= 0으로 이루어진 연결 요소의 수)를 구하세요.

def chunk(x, y, arr, visited):
    moves = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    stack = [(x,y)]
    chk = False
    
    # 출발점이 1이거나 방문했던 곳이면 그냥 chk는 false로 넘기기
    if arr[x][y] == 1 or visited[x][y]:
        return visited, False

    while stack:
        (x,y) = stack.pop()
        # 일단 하나를 뽑았고, 1이 아닌 값이므로, 한 chunk로 인식 chk = True
        chk = True
        visited[x][y] = True

        # 범위를 넘어가면 넘기기
        for dx, dy in moves:
            if (0>(x+dx) or (x+dx)>n-1) or (0>(y+dy) or (y+dy)>m-1):
                continue

            # 해당 좌표가 1이거나 방문 했으면 넘기기
            if arr[x+dx][y+dy] or visited[x+dx][y+dy]:
                continue
        
            # 범위를 안넘어 갔고 0인것을 확인했으니 상하좌우를 스택 추가
            stack.append([x+dx, y+dy])

    # 한 청크를 다 돌았으면 visited return
    return visited, chk
        
chk = False
cnt = 0
arr = [
        [0,0,1,1,0],
        [0,0,0,1,1],
        [1,1,1,1,1],
        [0,0,0,0,0]
    ]
n = len(arr)
m = len(arr[0])
visited = [[False] * m for _ in range(n)]

for i in range(n):
    for j in range (m):
        visited, chk = chunk(i, j, arr, visited)
        if chk:
            cnt +=1

print(cnt)
python

코테 TIP

👉
arr(mxn) 행렬에서
n = len(arr) m = len(arr[0])
행렬 초기화 ( 내부 리스트에서 ⇒ 외부 괄호 순 )
visited = [[False] * m for _ in range(n)]

잘못 접근했던 부분들

  • 연산자 우선 순위 문제 (‘|’ 와 ‘or’)
👉
if (0 > (x+dx) | (x+dx) > n-1) | (0 > (y+dy) | (y+dy) > m-1):
⇒ 비트 연산자 |, &, ^는 우선순위가 높아
(0 > ( (x+dx) | (x+dx) )) > n-1 이 꼴로 연산해버림
if (0 > (x+dx) or (x+dx) > n-1) or (0 > (y+dy) or (y+dy) > m-1):

python 코테에서 연산자는 반드시 “OR”, “AND”, “NOT”으로!!!

  • 스택 카운팅 (chk의 위치)
    👉
    실수 : pop이후 먼저 1이면 stack에서 방문 처리하고 넘기기 방식
     if (arr[x][y]) == 1 :
                visited[x][y] = True
                continue
     chk = True
    visited[x][y] = True
    python

    ⇒ 결국 1이 아닌 모든 0의 위치에서 카운팅 = 기본적으로 탐색 알고리즘에서 방문했더라도, 시작점 데이터는 스택에 들어감 = 오류

    👉
    쉽게 해결 : 스택 들어가기도 전에 그냥 밖에서 처리 하고 스택에는 시작점이 0인값만!
    # 출발점이 1이거나 방문했던 곳이면 그냥 chk는 false로 넘기기
        if arr[x][y] == 1 or visited[x][y]:
            return visited, False
    python

    ⇒ visited에 1인 값은 false로 바뀌지 않음!

[ 2. 단지 번호 붙이기 ]

[ 3. 물통 ]