
(1회 시도 성공!)
import java.io.*;
import java.util.*;
public class Main {
static char[][] arr;
static int[] dx = {-1,1,0,0};
static int[] dy = {0,0,-1,1};
static boolean[][] visited;
static int count = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T = Integer.parseInt(br.readLine());
for (int i = 0; i < T; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int h = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
arr = new char[h][w];
visited = new boolean[h][w];
for (int j = 0; j < h; j++) {
char[] s = br.readLine().toCharArray();
for (int k = 0; k < w; k++) {
arr[j][k] = s[k];
}
}
count = 0;
for (int j = 0; j < h; j++) {
for (int k = 0; k < w; k++) {
if(!visited[j][k] && arr[j][k] == '#'){
bfs(h, w, j,k);
count++;
}
}
}
bw.write(count+"\n");
}
br.close();
bw.close();
}
private static void bfs(int h, int w, int i, int j) {
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{i,j});
visited[i][j] = true;
while(!q.isEmpty()){
int[] cur = q.poll();
for (int k = 0; k < 4; k++) {
int ny = cur[0] + dy[k];
int nx = cur[1] + dx[k];
if(ny >=0 && ny < h && nx >= 0 && nx < w
&& !visited[ny][nx] && arr[ny][nx] == '#'){
visited[ny][nx] = true;
q.add(new int[]{ny, nx});
}
}
}
}
}
if(ny >=0 && ny < h && nx >= 0 && nx < w
&& !visited[ny][nx] && arr[ny][nx] == '#'){
q.add(new int[]{ny, nx});
}
while(!q.isEmpty()){
int[] cur = q.poll();
isited[cur[0]][cur[1]] = true;
for (int k = 0; k < 4; k++) {
int ny = cur[0] + dy[k];
int nx = cur[1] + dx[k];
if(ny >=0 && ny < h && nx >= 0 && nx < w
&& !visited[ny][nx] && arr[ny][nx] == '#'){
v
q.add(new int[]{ny, nx});
}
}
}
큐에서 뽑았을 때 방문체크를 했기 때문에 발생하는 문제였다
3. 방문 체크 순서의 변경이 대체 어떤 영향을 주기 때문에 이렇게 결과가 다를까?
4. 바로 중복된 탐색 값이 누적되어 들어가기 때문이다
아래 예시를 보면,
시작지점을 기준으로 상하좌우 탐색을 하며 큐에 차례대로 들어가는 것을 예상할 수 있다

다음 순서는 먼저 들어간 2번 자리의 상하좌우 값이 큐에 들어갈 것이다.
물론 이때 탐색한 1번은 들어가지 않는다!

문제는 다음 탐색에서 발생한다 이제 3번의 상하좌우 탐색을 하는데 7번 위치가 다시 들어가게 된다

방문체크를 큐에서 뽑을 때 하고 들어갈 때는 하지 않기 때문에,
큐에서 순서대로 뽑을 때 이렇게 중복으로 들어가는 문제가 발생하는 것이다
연쇄적으로 이 문제가 발생하게 된다면
큐에 많은 데이터가 쌓이게 되어 메모리 초과 이슈가 충분히 발생할 수 있다
private static void bfs(int h, int w, int i, int j) {
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{i,j});
visited[i][j] = true;
while(!q.isEmpty()){
int[] cur = q.poll();
for (int k = 0; k < 4; k++) {
int ny = cur[0] + dy[k];
int nx = cur[1] + dx[k];
if(ny >=0 && ny < h && nx >= 0 && nx < w
&& !visited[ny][nx] && arr[ny][nx] == '#'){
visited[ny][nx] = true;
q.add(new int[]{ny, nx});
}
}
}
}