문제
<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여기서 연결되었다는 것은 어떤 집이 좌우, 혹은 아래위로 다른 집이 있는 경우를 말한다. 대각선 상에 집이 있는 경우는 연결된 것이 아니다. <그림 2>는 <그림 1>을 단지별로 번호를 붙인 것이다. 지도를 입력하여 단지수를 출력하고, 각 단지에 속하는 집의 수를 오름차순으로 정렬하여 출력하는 프로그램을 작성하시오.
입력
첫 번째 줄에는 지도의 크기 N(정사각형이므로 가로와 세로의 크기는 같으며 5≤N≤25)이 입력되고, 그 다음 N 줄에는 각각 N개의 자료(0 혹은 1)가 입력된다.
출력
첫 번째 줄에는 총 단지수를 출력하시오. 그리고 각 단지내 집의 수를 오름차순으로 정렬하여 한 줄에 하나씩 출력하시오.
풀이(dfs)
n = int(input())
graph = [] #아파트 호수를 입력받을 배열
for _ in range(n):
graph.append(list(map(int,input())))
visited = [[0]*n for _ in range(n)] #아파트 호수와 같은 방문 그래프
dx = [-1,0,1,0] # x,y이동 좌표
dy = [0,1,0,-1]
def dfs(x,y,c):
visited[x][y] = 1 # 방문 표시
global nums # 아파트를 세기 위한 변수
if graph[x][y] == 1:
nums += 1
for i in range(4): # 4방향으로 반목문을 통한 좌표 이동
nx = x+dx[i]
ny = y+dy[i]
if 0<= nx < n and 0<= ny < n: # 벽을 넘지 않을때
if visited[nx][ny] == 0 and graph[nx][ny] == 1:
#방문하지 않았고 , 호수가 1이라면
dfs(nx,ny,c) # 재귀적으로 dfs를 수행
cnt = 1 # 아파트 단지를 세기 위한 변수
numlist = [] #총 단지수를 담기 위한 배열
nums = 0 # 총 단지수
for a in range(n):
for b in range(n):
if graph[a][b] == 1 and visited[a][b] == 0 :
dfs(a,b,cnt)
numlist.append(nums)
nums = 0 # 총 단지수를 담았다면 0으로 초기화
print(len(numlist)) # 총 단지수의 크기
for i in sorted(numlist): # 오름차순 정렬로 출력
print(i)
BFS
n = int(input())
graph = []
for _ in range(n):
graph.append(list(map(int,input())))
visited = [[0] * n for _ in range(n)]
dx = [-1,0,1,0]
dy = [0,1,0,-1]
def bfs(graph,x,y,cnt):
graph[x][y] = 0
queue = []
queue.append((x,y))
while queue :
x,y = queue.pop()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<n and 0<=ny<n:
if graph[nx][ny] == 1 and visited[nx][ny] == 0:
cnt += 1
graph[nx][ny] = 0
queue.append((nx,ny))
return cnt
cnt = 0
answer = []
for a in range(n):
for b in range(n):
if graph[a][b] == 1 and visited[a][b] == 0:
answer.append(bfs(graph,a,b,cnt+1))
print(len(answer))
for i in sorted(answer):
print(i)
문제 풀이
- 아파트 호수를 입력받을 graph 배열을 선언 후 반복문을 통해 입력 받음
- 아파트 호수와 같은 이차원 배열인 visited를 0으로 초기화
- dfs함수에서 각 graph를 순회하면서 배열을 초기화 하지 않는 선에서 방문하지 않았다면 재귀적으로 dfs 수행
- 2중 반목문을 통해서 방문하지 않고 배열의 값이 1이라면 dfs 수행 후 numslist에 nums를 담은 후 0으로 초기화
- 총 단지수와 오름차순으로 정렬된 값 출력
'Algorithm' 카테고리의 다른 글
[BOJ/백준] 1012번 유기농 배추 (0) | 2021.03.09 |
---|---|
[BOJ/백준] 2178번 미로탐색 (0) | 2021.03.06 |
[프로그래머스] LV3 베스트 앨범 (0) | 2021.03.03 |
[BOJ/백준] 11403번 경로 찾기 (0) | 2021.03.02 |
[BOJ/백준] 11404번 플로이드 (0) | 2021.03.02 |