반응형
문제
ANT가 처음 알고리즘 대회를 개최하게 되면서 현수막을 내걸었다.
저번 학기 영상처리 수업을 듣고 배웠던 지식을 최대한 응용 해보고 싶은 혁진이는 이 현수막에서 글자가 몇 개인지 알아보는 프로그램을 만들려 한다.
혁진이는 우선 현수막에서 글자인 부분은 1, 글자가 아닌 부분은 0으로 바꾸는 필터를 적용하여 값을 만드는데 성공했다.
그런데 혁진이는 이 값을 바탕으로 글자인 부분 1이 상, 하, 좌, 우, 대각선으로 인접하여 서로 연결되어 있다면 한 개의 글자라고 생각만 하였다.
혁진이가 필터를 적용하여 만든 값이 입력으로 주어졌을 때, 혁진이의 생각대로 프로그램을 구현하면 글자의 개수가 몇 개인지 출력하여라.
입력
첫 번째 줄에는 현수막의 크기인 M와 N가 주어진다. (1 ≤ M, N ≤ 250)
두 번째 줄부터 M+1 번째 줄까지 현수막의 정보가 1과 0으로 주어지며, 1과 0을 제외한 입력은 주어지지 않는다.
출력
혁진이의 생각대로 프로그램을 구현했을 때, 현수막에서 글자의 개수가 몇 개인지 출력하여라.
예제 입력 1
8 19
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1 0 0 0 1 0 1 1 1 1 1 0
0 0 1 0 1 0 0 1 1 0 0 1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 1 0 0 0
0 1 1 1 1 1 0 1 0 1 0 1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
예제 출력 1
3
소스코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
private static BufferedReader br;
private static StringTokenizer st;
private static int M, N, cnt;
private static int[][] map;
private static boolean[][] visited;
private static int[] dx = { -1, -1, -1, 0, 0, 1, 1, 1 };
private static int[] dy = { -1, 0, 1, -1, 1, -1, 0, 1 };
static class Point {
int r, c;
public Point(int r, int c) {
super();
this.r = r;
this.c = c;
}
@Override
public String toString() {
return "Point [r=" + r + ", c=" + c + "]";
}
}
public static void main(String[] args) throws IOException {
br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine());
M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
map = new int[M][N];
for (int r = 0; r < M; r++) {
st = new StringTokenizer(br.readLine());
for (int c = 0; c < N; c++) {
map[r][c] = Integer.parseInt(st.nextToken());
}
}
cnt = 0;
visited = new boolean[M][N];
for (int r = 0; r < M; r++) {
for (int c = 0; c < N; c++) {
if (map[r][c] == 1 && !visited[r][c]) {
cnt++;
bfs(r, c);
}
}
}
System.out.println(cnt);
}
private static void bfs(int r, int c) {
Queue<Point> queue = new LinkedList<>();
queue.add(new Point(r, c));
visited[r][c] = true;
while (!queue.isEmpty()) {
Point p = queue.poll();
for (int d = 0; d < 8; d++) { // 상,하,좌,우,대각선 -> 8방 탐색
int nx = p.r + dx[d];
int ny = p.c + dy[d];
if (isIn(nx, ny) && !visited[nx][ny] && map[nx][ny] == 1) {
visited[nx][ny] = true;
queue.add(new Point(nx, ny));
}
}
}
}
private static boolean isIn(int r, int c) {
return r >= 0 && r < M && c >= 0 && c < N;
}
}
반응형
'코딩테스트 > 그래프 탐색' 카테고리의 다른 글
[Java] 백준 2617번 : 구슬 찾기 (0) | 2022.05.11 |
---|---|
[Java] 백준 15900번 : 나무 탈출 (0) | 2022.05.10 |
[Java] 백준 12852번 : 1로 만들기 2 (0) | 2022.05.09 |
[Java] 백준 12761번 : 돌다리 (0) | 2022.05.09 |
[Java] 백준 6118번 : 숨바꼭질 (0) | 2022.05.09 |