n = int(input())
# 2차원 배열 지도
arr = []
# 방문 여부 확인용 2차원 배열
visited =[[False]*n for _ in range(n)]
# 단지 내 가구 수
count = 0
# 단지 내 가구 수 리스트
count_list = []
for i in range(n):
arr.append(list(map(int,list(input()))))
# dfs 함수
def dfs(x,y):
global count
# 집이 존재한지 / 방문한 적 있는지 여부 확인
if arr[x][y] == 1 and not visited[x][y]:
# 방문 처리
visited[x][y] = True
# 단지 내 가구 수 증가
count += 1
# 상-하-좌-우로 이동하기 위한 값
nx = [-1,1,0,0]
ny = [0,0,-1,1]
for i in range(4):
# 상-하-좌-우 인덱스 설정
temp_x = x+nx[i]
temp_y = y+ny[i]
# 배열 범위를 벗어나는지 여부 확인
if temp_x >= 0 and temp_x < n and temp_y >= 0 and temp_y < n:
# 다음 위치가 집이 존재하는지 / 방문한 적 있는지 여부 확인
if arr[temp_x][temp_y] == 1 and not visited[temp_x][temp_y]:
# 집이 존재하고, 방문한 적이 없으면 방문(dfs 재귀)
dfs(temp_x,temp_y)
return True
# 집이 존재하지 않거나 방문한 적 있다면 PASS
else :
return False
# 모든 위치에 관하여 반복문으로 돌면서 dfs 처리
for i in range(n):
for j in range(n):
if dfs(i,j): # 만약에 True를 반환하면 하나의 단지가 만들어지고, count를 초기화(새로운 단지 내 가구수를 찾기 위해)
count_list.append(count)
count = 0
# 단지 개수 출력
print(len(count_list))
# 단지 내 가구수 오름차순 정렬
count_list.sort()
# 단지 내 가구수 차례대로 출력
for i in range(len(count_list)):
print(count_list[i])
이번 문제는 깊이(Depth)나 최단경로를 물어보는 것이 아니라, 연결된 영역(집)의 개수를 카운팅하는 문제이기 때문에 탐색 알고리즘 중에서도 DFS 알고리즘을 사용하여 풀어야한다는 것을 파악할 수 있었다.
먼저, 연결된 부분(단지)에 존재하는 집의 개수와 연결된 부분(단지)의 개수가 몇 개인지 모두 세주어야 하기 때문에 단지 내 가구 수를 카운팅해주는 count 변수와 count_list 배열을 선언하였다.
나머지 내용들은 이전에 다루었던 dfs문제에서도 언급했듯이, 방문 여부를 체크하는 visited 배열과 재귀함수(def dfs)를 사용하여 문제를 풀이할 수 있었다.
다만 조심해야 할 점은 단지에 속하는 집의 개수를 오름차순으로 정렬해야 한다는 것이다. (다 맞았는데 이것 때문에 1회 실패했다고 한다,,,)
DFS 알고리즘에 대해 활용해볼 수 있는 좋은 문제였다 :)
'Algorithm 💡 > DFS' 카테고리의 다른 글
[백준 11724번] 연결 요소의 개수 (0) | 2023.02.15 |
---|---|
[백준 1012번] 유기농 배추 (0) | 2023.02.13 |
[백준 2606번] 바이러스 (0) | 2023.02.12 |
[백준 1260번] DFS와 BFS (0) | 2023.02.12 |
[DFS] DFS 알고리즘의 기본 개념 및 활용법 (0) | 2023.02.10 |