블로그 이사🏡 했습니다. 👉🏻 둘러보기
본문 바로가기
  • What Get's You Here, Won't Get You There
CS/Problem-solving

백준 2667번 파이썬

by OMIN_ 2022. 5. 5.

문제 링크

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

 

2667번: 단지번호붙이기

<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여

www.acmicpc.net

 

시간 제한 / 메모리 제한

1 초 128 MB

 

문제

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

 

입력

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

출력

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

예제 입력

7
0110100
0110101
1110101
0000111
0100000
0111110
0111000

예제 출력

3
7
8
9

 

문제 풀이를 위해 생각한 것

  1. 관리해야 하는 변수는 총 단지 수, 단지 내 집의 수
  2. N*N 크기의 지도에서, 각 지점마다, 방문여부, 아파트 존재 여부를 고려해 DFS를 수행한다.
  3. 지도의 해당 지점이 '1'일 때, 아직 방문하지 않았을 때 DFS를 수행하고, DFS 수행 횟수는 곧 총 단지 수가 된다.
  4. DFS로 인접한 아파트의 갯수를 모두 탐색하고, 한 단지 내 집의 수를 리턴한다.
  5. DFS 리턴 값을 배열에 삽입하고, 지도 탐색이 완료되면 배열을 오름차순으로 정렬한 뒤, 총 단지 수, 단지 내 집의 수 오름차순 정렬 결과를 차례대로 출력한다.

 

사용한 자료구조 / 알고리즘

2차원 배열 / DFS(재귀)

결국 모든 지도를 탐색해야 하기에, BFS로도 해결할 수 있는 문제이다.

 

풀이 코드

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)

n = int(input())
board = [list(input().strip()) for _ in range(n)]
visited = [[False for _ in range(n)] for _ in range(n)]
dx = (1, -1, 0, 0)
dy = (0, 0, 1, -1)
cnt = 0
cntList = []


def dfs(x, y):

    visited[x][y] = True
    _cnt = 1

    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]

        if 0 <= nx < n and 0 <= ny < n and board[nx][ny] == '1' and not visited[nx][ny]:
            _cnt += dfs(nx, ny)

    return _cnt


for i in range(n):
    for j in range(n):
        if board[i][j] == '1' and not visited[i][j]:
            cnt += 1
            cntList.append(dfs(i, j))

cntList.sort()
print(cnt)
for c in cntList:
    print(c)

 

시간 복잡도 분석

O(N^2).

모든 지도를 탐색해야 하며, 문제에서 주어지는 지도의 크기는 N^2이다.

따라서 시간 복잡도는 O(N^2)이다.

 

문제에서 중요한 부분

2022.05.05 - [CS/Algorithm] - 백준 1743번 파이썬

 

백준 1743번 파이썬

문제 링크 https://www.acmicpc.net/problem/1743 1743번: 음식물 피하기 첫째 줄에 통로의 세로 길이 N(1 ≤ N ≤ 100)과 가로 길이 M(1 ≤ M ≤ 100) 그리고 음식물 쓰레기의 개수 K(1 ≤ K ≤ N×M)이 주어진다..

omins.tistory.com

위 문제와 접근 방식이 매우 유사했다. DFS 내부에서 카운트하고, DFS 결과를 전역변수로 관리하는 것.

'CS > Problem-solving' 카테고리의 다른 글

백준 2468번 파이썬  (0) 2022.05.05
백준 2583번 파이썬  (0) 2022.05.05
백준 1743번 파이썬  (0) 2022.05.05
백준 1182번 파이썬  (0) 2022.05.05
백준 2178번 파이썬  (0) 2022.05.02

댓글