[백준] 단지번호붙이기

subin·2023년 4월 13일
0

🥰Coding Test

목록 보기
14/22
post-thumbnail

문제

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

TC

DFS

  • 인접 행렬로 구현할 시 O(V^2)
  • 인접 리스트로 구현할 시 O(V+E)

BFS

  • 인접 행렬로 구현할 시 O(V^2)
  • 인접 리스트로 구현할 시 O(V+E)

Idea

전형적인 DFS, BFS 문제로 두 가지 방법으로 모두 풀 수 있는 문제이다.

그래프의 탐색 시작점을 모르기 때문에 전체를 돌면서 1인 지점에서 탐색을 시작한다.
탐색 중 1인 부분은 0으로 바꿔 다시 방문하지 않도록 하고, 한 번의 DFS or BFS가 끝나게 되면 더 이상 확장이 불가능 하므로 마을 하나가 생기게 된다.

code (Python)

DFS 재귀 풀이

def dfs(x, y):
    global cnt

    if x < 0 or x >= n or y < 0 or y >= n:
        return False

    if graph[x][y] == 1:
        cnt += 1
        graph[x][y] = 0

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

n = int(input())
graph = [list(map(int, input())) for _ in range(n)]

# 총 단지수
village = 0
# 각 단지내 집의 수
home = []
cnt = 0
for i in range(n):
    for j in range(n):
        if dfs(i, j):
            village += 1
            home.append(cnt)
            cnt = 0

print(village)
for h in sorted(home):
    print(h)

DFS 풀이

def dfs(x, y):
    global cnt
    # 범위를 벗어나면 false
    if x < 0 or x >= n or y < 0 or y >= n:
        return False
    if graph[x][y] == 1:
        cnt += 1
        graph[x][y] = 0
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            dfs(nx, ny)
        return True
    return False

# 지도의 크기
n = int(input())
graph = [list(map(int, input())) for _ in range(n)]

dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

# 총 단지 수
village = 0
# 각 단지내 집의 수
home = []
cnt = 0
for i in range(n):
    for j in range(n):
        if graph[i][j] == 1:
            village += 1
            dfs(i, j)
            home.append(cnt)
            cnt = 0

print(village)
for h in sorted(home):
    print(h)

BFS 풀이

from collections import deque

def bfs(x, y):
    global cnt

    queue = deque()
    queue.append((x, y))
    graph[x][y] = 0
    cnt += 1

    while queue:
        x, y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            # 범위 내이고 집이 있다면
            if 0 <= nx < n and 0 <= ny < n and graph[nx][ny] == 1:
                graph[nx][ny] = 0
                cnt += 1
                queue.append((nx, ny))

# 지도의 크기
n = int(input())
graph = [list(map(int, input())) for _ in range(n)]

dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

# 총 단지 수
village = 0
# 각 단지내 집의 수
home = []
cnt = 0
for i in range(n):
    for j in range(n):
        if graph[i][j] == 1:
            village += 1
            bfs(i, j)
            home.append(cnt)
            cnt = 0

print(village)
for h in sorted(home):
    print(h)

self code review

전형적인 DFS, BFS 문제로 문제를 푸는데 있어서 어려움은 없었다.

연습도 할겸, 세 가지 방법으로 풀어봤는데 소요 시간을 비교해보면 다음과 같다.
DFS (116ms) < DFS 재귀 (124ms) < BFS (152ms)

아무래도 최단 거리를 구하는 문제가 아니기 때문에 DFS가 조금 더 빠르지 않았나 싶다.

profile
한번뿐인 인생! 하고싶은게 너무 많은 뉴비의 deep-dive 현장

0개의 댓글