728x90
📢 '이것이 코딩 테스트다 with 파이썬' 책을 공부하고 복습하기 위해 작성했습니다.
문제
N X M 크기의 얼음 틀 모양이 주어졌을 때 생성되는 총 아이스크림의 개수를 구하라.
구멍이 뚫려 있는 부분끼리 상, 하, 좌, 우로 붙어 있는 경우 서로 연결된 것으로 간주한다.
입력 조건
- 첫 번째 줄에 얼음 틀의 세로 길이 N과 가로 길이 M이 주어진다. (1 <= N, M <= 1,000)
- 두 번째 줄부터 N+1번째 줄까지 얼음 틀의 형태가 주어진다.
- 이때 구멍이 뚫려있는 부분은 0, 그렇지 않은 부분은 1이다.
출력 조건
- 한 번에 만들 수 있는 아이스크림의 개수를 출력한다.
입력 예시 1
4 5
00110
00011
11111
00000
출력 예시 1
3
입력 예시 2
15 14
00000111100000
11111101111110
11011101101110
11011101100000
11011111111111
11011111111100
11000000011111
01111111111111
00000000011111
01111111111000
00011111111000
00000001111000
11111111110011
11100011111111
11100011111111
출력 예시 2
8
나의 풀이
N, M = map(int, input().split())
board = [list(map(str, input())) for _ in range(N)]
visited = [[0] * M for _ in range(N)]
# 상하좌우
dxy = [(-1, 0), (1, 0), (0, -1), (0, 1)]
"""
1. 얼음틀을 순회하며 구멍(0)을 발견한다.
2. 구멍에서부터 상하좌우로 연결된 구멍을 체크한다.(DFS)
3. 더 이상 구멍이 없다면, 아이스크림 +1
얼음틀을 다시 순회하며, 체크안된 구멍을 체크(계속)
"""
def check(x, y):
for di, dj in dxy:
ni = x + di
nj = y + dj
if ni < 0 or nj < 0 or ni >= N or nj >= M:
continue
if board[ni][nj] == '0' and visited[ni][nj] == 0:
visited[ni][nj] = 1
check(ni, nj)
cnt = 0
for i in range(0, N):
for j in range(0, M):
# 구멍이 뚫려있고 체크한 적 없으면
if board[i][j] == '0' and visited[i][j] == 0:
visited[i][j] = 1
check(i, j)
cnt += 1
print(cnt)
해설
DFS를 이용해 '0'인 값이 상, 하, 좌, 우로 연결되어 있는 노드의 묶음을 찾아줄 수 있다.
- 특정한 지점의 주변 상, 하, 좌, 우를 살펴본 뒤에 주변 지점 중에서 값이 '0'이면서 아직 방문하지 않은 지점이 있다면 해당 지점을 방문한다.
- 방문한 지점에서 다시 상, 하, 좌, 우를 살펴보면서 방문을 다시 진행하면, 연결된 모든 지점을 방문할 수 있다.
- 1 ~ 2 번의 과정을 모든 노드에 반복하며 방문하지 않은 지점의 수를 센다.
728x90
'Algorithm' 카테고리의 다른 글
[이코테] 05. 정렬 (1) | 2024.01.05 |
---|---|
[이코테] 04. DFS / BFS - 미로 탈출 (1) | 2024.01.02 |
[이코테] 04. DFS / BFS (1) | 2024.01.02 |
[이코테] 04. DFS / BFS - 자료구조 기초 (0) | 2024.01.02 |