[Java] 백준 4963번

박세윤·2022년 7월 17일
0

BaekJoon Online Judge

목록 보기
74/95
post-thumbnail

백준 4963번

섬의 개수

문제

정사각형으로 이루어져 있는 섬과 바다 지도가 주어진다. 섬의 개수를 세는 프로그램을 작성하시오.

한 정사각형과 가로, 세로 또는 대각선으로 연결되어 있는 사각형은 걸어갈 수 있는 사각형이다.

두 정사각형이 같은 섬에 있으려면, 한 정사각형에서 다른 정사각형으로 걸어서 갈 수 있는 경로가 있어야 한다. 지도는 바다로 둘러싸여 있으며, 지도 밖으로 나갈 수 없다.

입력

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

둘째 줄부터 h개 줄에는 지도가 주어진다. 1은 땅, 0은 바다이다.

입력의 마지막 줄에는 0이 두 개 주어진다.

출력

각 테스트 케이스에 대해서, 섬의 개수를 출력한다.

예제

알고리즘 분류

  • 그래프 이론
  • 그래프 탐색
  • 너비 우선 탐색
  • 깊이 우선 탐색

코드

import java.util.*;
import java.io.*;

public class Main {
	public static int w, h;
	public static int map[][];
	public static int dx[] = {0, 1, 1, 1, 0, -1, -1, -1}; // 상부터 시계방향으로 
	public static int dy[] = {1, 1, 0, -1, -1, -1, 0, 1};
	public static boolean visited[][];
	public static int island = 0;
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		while(true) {
			st = new StringTokenizer(br.readLine(), " ");
			
			w = Integer.parseInt(st.nextToken());
			h = Integer.parseInt(st.nextToken());
			
			if((w == 0) && (h == 0))
				break;
			
			map = new int[h][w];
			visited = new boolean[h][w];
			island = 0;
			
			for(int i=0; i<h; i++) {
				st = new StringTokenizer(br.readLine());
				
				for(int j=0; j<w; j++)
					map[i][j] = Integer.parseInt(st.nextToken());
			}
			
			for(int i=0; i<h; i++) {
				for(int j=0; j<w; j++) {
					if(map[i][j] == 1 && !visited[i][j]) {
						visited[i][j] = true;
						DFS(i, j);
						island++;
					}
				}
			}
			
			System.out.println(island);
		}
	}
	
	public static void DFS(int row, int col) {
		for(int i=0; i<8; i++) {
			int nx = row + dx[i];
			int ny = col + dy[i];
			
			if(nx<0 || nx>=h || ny<0 || ny>=w || map[nx][ny]==0 || visited[nx][ny])
				continue;
			
			visited[nx][ny] = true;
			DFS(nx, ny);
		}
		
		return;
	}
}

풀이

2차원 맵을 만들어야 하므로, 2차원 배열을 사용하여 DFS로 문제를 해결한다. BFS였으면 queue를 활용했을 것이다.

dx, dy를 활용하여 8방향을 설정하고, DFS 함수에서 설정한 dx와 dy를 활용하여 nx와 ny를 설정한다.

visited 배열을 활용하여 이전에 방문했는지 여부를 확인하고, 좌표가 맵 크기를 벗어나거나, 이전에 방문했던 곳으로 판단하면 continue를 통해 넘어간다.

섬의 수는 DFS가 한번 끝날 때마다 추가해준다.

profile
개발 공부!

0개의 댓글

관련 채용 정보