백준 2667 : 단지번호 붙이기 (그래프 탐색)

seow·2022년 2월 1일
0

알고리즘

목록 보기
3/6

  1. N의 범위가 좁다. 1초 가능 연산 수가 약 2000만이다. 25*25 모두 확인한다 하더라도 한참 못미침. -> 시간 제한은 딱히 고려 안해도 괜찮다.

  2. 문제를 읽어보면 Start 지점부터 탐색 가능한 지점 끝까지 탐색을 진행하면 된다. 탐색 방문 지점 리스트를 만들어 놓고 끝까지 탐색한 후 len(visit_list)를 뽑아주면 된다.

  3. 끝까지 탐색하고 방문한 리스트를 뽑아주면 되기 때문에 둘 중 아무거나 사용하면 된다. 필자는 BFS가 좋다. (return 뽑기 좋다.)

from collections import deque

"""
    정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다.
    철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다.
    여기서 연결되었다는 것은 어떤 집이 좌우, 혹은 아래위로 다른 집이 있는 경우를 말한다.
    대각선상에 집이 있는 경우는 연결된 것이 아니다. <그림 2>는 <그림 1>을 단지별로 번호를 붙인 것이다.
    지도를 입력하여 단지수를 출력하고, 각 단지에 속하는 집의 수를 오름차순으로 정렬하여 출력하는 프로그램을 작성하시오.
"""

N = 7
arr = [[0,1,1,0,1,0,0],
    [0,1,1,0,1,0,1],
    [1,1,1,0,1,0,1],
    [0,0,0,0,1,1,1],
    [0,1,0,0,0,0,0],
    [0,1,1,1,1,1,0],
    [0,1,1,1,0,0,0]]


move = [(1, 0), (-1, 0), (0, 1), (0, -1)]
def find_number(i, j, visited):
    visited.append((i, j))
    queue = deque([(i, j)])
    arr[i][j] = 0

    while queue :
        now = queue.popleft()
        i, j = now
        for m in move:
            dx, dy = m
            if 0 <= i + dx < N and 0 <= j + dy < N and arr[i + dx][j + dy] == 1:
                queue.append((i + dx, j + dy))
                arr[i+dx][j+dy] = 0
                visited.append((i + dx, j + dy))

    return visited


visited = []
visit_nums = []
for i in range(N):
    for j in range(N):
        if arr[i][j] == 1:
            visited = find_number(i, j, visited)
            visit_nums.append(len(visited))
            visited = []

visit_nums.sort()
print(len(visit_nums))
for v in visit_nums:
    print(v)

profile
딥러닝 공부

0개의 댓글