티스토리 뷰

728x90
 

4963번: 섬의 개수

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

www.acmicpc.net

문제

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

 

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

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

입력

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

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

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

출력

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

 

 

 

a[i-1][j-1] a[i-1][j] a[i-1][j+1]
a[i][j-1] a[i][j] a[i][j+1]
a[i+1][j-1] a[i+1][j] a[i+1][j+1]

배열의 값 순서대로 함수를 호출하면서 그 배열의 값이 1이면, 주변에 있는 값이 1인지 확인하고 만약 1이라면 그 배열으로 재귀호출한다. 재귀호출으로 점점 1이 있는 배열으로 더 깊이 들어가므로 DFS에 속한다. 위 표에서 함수를 호출한 배열의 값이 보라색으로 칠한 a[i][j]라면 표에 있는 나머지 8값을 확인하면 된다. 8개의 배열 값은 dx dy의 배열에 각각 저장했다. 만약 다음 값이 1이라면 초기값을 1로 설정한 tmp 값에 1씩 더해 배열 값에 넣어준다. 그러면 하나의 섬을 발견한 가장 초기의 1값을 제외하고는 한 섬에 연결된 1이 점점 커지게 될 것이고, 함수를 호출한 후 1의 개수가 섬의 개수가 된다. 예를 들어 배열 값이 아래 표와 같을 경우, 함수를 실행 한 후의 배열 값은 그 아래의 표와 같아진다.

 

1 0 1 0 0
1 0 0 0 0
1 0 1 0 1
1 0 0 1 0

 

1 0 1 0 0
2 0 0 0 0
3 0 1 0 3
4 0 0 2 0

 

package baekjoon;
import java.util.StringTokenizer;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;

public class B_4963 {
	static StringBuilder sb;
	static int[][] array;
	static int[][] visited;
	static int tmp;
	static int w, h;
	static int[] dx = {-1, -1, -1, 0, 0, 1, 1, 1};
	static int[] dy = {-1, 0, 1, -1, 1, -1, 0, 1};
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		sb = new StringBuilder();
		while(true) {
			int count = 0;
			StringTokenizer st = new StringTokenizer(br.readLine());
			w = Integer.parseInt(st.nextToken());
			h = Integer.parseInt(st.nextToken());
			if(w == 0 && h == 0)
				break;
			array = new int[h][w];
			visited = new int[h][w];
 			for(int i=0;i<h;i++) {
				st = new StringTokenizer(br.readLine());
				for(int j=0;j<w;j++) {
					array[i][j] = Integer.parseInt(st.nextToken());
				} // 배열에 값 대입
			}
			for(int i=0;i<h;i++) 
				for(int j=0;j<w;j++) {
					tmp = 1;
					islandNum(i, j);
				}
			for(int i=0;i<h;i++) 
				for(int j=0;j<w;j++)
					if(array[i][j] == 1)
						count++; // 배열의 1의 개수가 섬의 개수와 같음
			sb.append(count+"\n");
		}
		System.out.println(sb);
	}
	static void islandNum(int a, int b) {
		if(visited[a][b] == 1)
			return;
		visited[a][b] = 1;
		if(array[a][b] == 0)
			return;
		else {
			for(int i=0;i<dx.length;i++){
					int x = a + dx[i];
					int y = b + dy[i];
					if(0 <= x && x < h && 0 <= y && y < w && array[x][y] == 1 && visited[x][y] == 0) {
						// 다음에 가야할 값이 배열의 범위 안에 있고 array 값이 1이면
						array[x][y] = ++tmp;
						islandNum(x, y); // 다음 값으로 재귀 
					}
				}
		}

	}
}

 

 

728x90
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함