킹의 개발일지

섬의 개수(백준 4963번) 본문

문제풀이

섬의 개수(백준 4963번)

k1ng 2022. 12. 6. 18:46

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

 

4963번: 섬의 개수

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 지도의 너비 w와 높이 h가 주어진다. w와 h는 50보다 작거나 같은 양의 정수이다. 둘째 줄부터 h개 줄에는 지도

www.acmicpc.net

해당 문제는 기본적인 그래프 탐색을 적용하면 풀 수 있는 문제이다.

BFS 알고리즘을 사용해서 문제를 풀었는데, 일반적인 문제가 방향벡터가 동서남북 4가지만 존재하는 반면, 해당 문제는 나이트의 이동처럼 특정 좌표에서 대각선을 탐색하는 벡터가 추가적으로 필요하다.

 

최종적인 방향 벡터는 다음과 같다.

dx = [1, 0, -1, 0, -1, -1, 1, 1]
dy = [0, 1, 0, -1, -1, 1, -1, 1]

각각 하, 우, 상, 좌, 왼쪽 위 대각선, 오른쪽 위 대각선, 왼쪽 아래 대각선, 오른쪽 아래 대각선을 체크하는 방향벡터이다.

 

이후 2차원 행렬을 2중 for문을 돌면서 방문해주는데, bfs() 메서드를 사용해서 방문체크를 진행해주면서 카운트를 올려준다. 각 bfs 호출에서 방문했던 좌표를 visited 처리하기 떄문에, 방문된 좌표는 for문에서 걸러지게 되고 문제를 해결할 수 있다.

 

다음은 전체 코드이다.

import sys
from collections import deque

dx = [1, 0, -1, 0, -1, -1, 1, 1]
dy = [0, 1, 0, -1, -1, 1, -1, 1]

def bfs(x, y):
    q = deque()
    q.append((x, y))
    
    while q:
        cx, cy = q.popleft()
        for dir in range(8):
            nx = cx + dx[dir]
            ny = cy + dy[dir]
            if 0 <= nx < h and 0 <= ny < w and not visited[nx][ny]:
                if matrix[nx][ny] == 1:
                    visited[nx][ny] = True
                    q.append((nx, ny))

while True:
    w, h  = map(int, sys.stdin.readline().split())
    if w == 0 and h == 0: break
    matrix = [ list(map(int, sys.stdin.readline().split())) for _ in range(h) ]
    visited = [[False for _ in range(w)] for _ in range(h)]
    cnt = 0
    for i in range(h):
        for j in range(w):
            if not visited[i][j] and matrix[i][j] == 1:
                cnt += 1 
                visited[i][j] = True
                bfs(i, j)
    print(cnt)

'문제풀이' 카테고리의 다른 글

행성 터널 (백준 2997번)  (0) 2022.12.10
퇴사 (백준 14051번)  (0) 2022.12.08
연구소 (백준 14502번)  (0) 2022.12.04
치킨 배달 (백준 15686번)  (0) 2022.12.01
게임 개발(이코테 실전문제)  (0) 2022.11.30