1 minute read

백준 문제 중 2667번

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

문제

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

img

입력

첫 번째 줄에는 지도의 크기 N(정사각형이므로 가로와 세로의 크기는 같으며 5≤N≤25)이 입력되고, 그 다음 N줄에는 각각 N개의 자료(0혹은 1)가 입력된다.

출력

첫 번째 줄에는 총 단지수를 출력하시오. 그리고 각 단지내 집의 수를 오름차순으로 정렬하여 한 줄에 하나씩 출력하시오.


이 문제는 지도를 그래프의 한 형태로 보는게 핵심이다. 지도를 탐색중에 1을 만나게 되면 해당 인덱스를 기준으로 상하좌우가 연결된 그래프로 생각하고 DFS 나 BFS로 더 이상 연결되는 1이 없을때까지 탐색을 진행하면된다.

지도를 순차적으로 방문하다가 1을 만나게되면 그 인덱스를 기준으로 상하 좌우를 DFS로 탐색하게끔 코드를 짰다.

n = int(input())

maps = [None]*n

 # 문자열을 list()로 감싸면 알아서 쪼개주는걸 이용했다.
for i in range(n):
    maps[i]=list(input())


 # 인덱스와 cnt를 매개변수로 받는 dfs함수 선언
def dfs(i,j,cnt=0):

     # 만약 인덱스가 범위를 벗어나거나,
     # 지도에서 1이 아닌곳을 만났을 경우 바로 함수를 종료한다.
    if i<0 or i>n-1 or j<0 or j>n-1 or maps[i][j]!='1':
        return cnt

     # dfs가 호출됐다면 집을 만난것이므로 cnt를 1 증가시킨다.
    cnt += 1

     # 이미 방문한 집은 0으로 바꾸어 표시해준다.
    maps[i][j] = '0'

     # 상하좌우의 dfs 가 호출될때마다 cnt를 최신화한다.
    cnt = dfs(i+1,j,cnt)
    cnt = dfs(i,j+1,cnt)
    cnt = dfs(i-1,j,cnt)
    cnt = dfs(i,j-1,cnt)    

    return cnt

result = []

for i in range(n):
    for j in range(n):
        if maps[i][j]=='1':
            result.append(dfs(i,j))

result.sort()
print(len(result))
for r in result: print(r)

7
0110100
0110101
1110101
0000111
0100000
0111110
0111000
3
7
8
9

그런데 위 코드에서 cnt가 너무 자주 반복되는 형태로 호출되어서 더 깔끔하게 정리를 하고 싶었고 global을 통해 전역변수로 cnt의 반복을 줄였다.

n = int(input())

maps = [None]*n

for i in range(n):
    maps[i]=list(input())


cnt = 0

def dfs(i,j):
    global cnt

    if i<0 or i>n-1 or j<0 or j>n-1 or maps[i][j]!='1':
        return

    cnt += 1
    maps[i][j] = '0'

    dfs(i+1,j)
    dfs(i,j+1)
    dfs(i-1,j)
    dfs(i,j-1)    


result = []

for i in range(n):
    for j in range(n):
        if maps[i][j]=='1':
            dfs(i,j)
            result.append(cnt)
            cnt = 0

result.sort()
print(len(result))
for r in result: print(r)

Leave a comment