https://www.acmicpc.net/problem/2573
2573번: 빙산
첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을
www.acmicpc.net
이 문제를 보고 외곽부터 BFS 알고리즘을 돌려 옆에 빙산이 있을 때마다 그 수를 -1를 시키면 된다.
그 후, 남아있는 빙산을 시작점으로 다시 BFS 알고리즘을 돌려 해당 개수가 2개 이상이 나오면 종료시키고, 아니면 다시 처음 과정으로 돌아가 반복한다.
package BFS;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class N2573 {
public static class Pos2 {
int r, c, dist;
public Pos2(int r, int c, int dist) {
this.r = r;
this.c = c;
this.dist = dist;
}
}
private static final int[] DR = {1, 0, -1, 0};
private static final int[] DC = {0, 1, 0, -1};
public static void Bfs(Queue<Pos2> q, int R, int C, String[][] maze) {
while (!q.isEmpty()) {
Pos2 cur = q.poll(); // 큐에서 하나를 뽑아냄
for (int i = 0; i < DR.length; i++) { // 인접한 칸으로 탐색 진행
int nextR = cur.r + DR[i];
int nextC = cur.c + DC[i];
if (nextR < 0 || nextR >= R || nextC < 0 || nextC >= C) {
continue; // 다음 탬색할 위치가 미로를 벗어난 위치이거나 이미 방문한 곳이거나 장애물인 경우 탐색에서 제외
}
if (Integer.parseInt(maze[nextR][nextC]) >= 1) {
maze[nextR][nextC] = String.valueOf(Integer.parseInt(maze[nextR][nextC]) - 1);
}
}
}
}
public static int Bfs2(Queue<Pos2> q, int R, int C,String[][] maze, boolean[][] visited) {
while (!q.isEmpty()) {
Pos2 cur = q.poll(); // 큐에서 하나를 뽑아냄
for (int i = 0; i < DR.length; i++) { // 인접한 칸으로 탐색 진행
int nextR = cur.r + DR[i];
int nextC = cur.c + DC[i];
int nextDist = cur.dist + 1;
if (nextR < 0 || nextR >= R || nextC < 0 || nextC >= C || visited[nextR][nextC]) {
continue; // 다음 탬색할 위치가 미로를 벗어난 위치이거나 이미 방문한 곳이거나 장애물인 경우 탐색에서 제외
}
if(Integer.parseInt(maze[nextR][nextC]) == 0)
{
continue;
}
q.add(new Pos2(nextR, nextC, nextDist));
visited[nextR][nextC] = true;
}
}
return 1;
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
final int R = Integer.parseInt(st.nextToken());
final int C = Integer.parseInt(st.nextToken());
int time = 1;
int count = 0;
boolean isfirst = true;
Queue<Pos2> q = new LinkedList<>();
boolean[][] visited = new boolean[R][C];
// 미로 입력 받기
String[][] maze = new String[R][C];
for (int i = 0; i < R; i++) {
String curRow = br.readLine();
for (int j = 0; j < C; j++) {
String curCol[] = curRow.split(" ");
//char curCol = curRow.charAt(j);
if (curCol[j].equals("0")) {
q.add(new Pos2(i, j, 0));
}
maze[i][j] = curCol[j];
}
}
Bfs(q, R, C, maze);
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (Integer.parseInt(maze[i][j]) >= 1 && !visited[i][j]) {
q.add(new Pos2(i, j, 0));
visited[i][j] = true;
count = count + Bfs2(q, R, C, maze,visited);
}
}
}
if (count >= 2) {
System.out.println(time);
return;
}
if (count <= 0) {
System.out.println(0);
return;
}
// BFS 진행
while (true){
count = 0;
if (isfirst)
{
isfirst = false;
continue;
}
else
{
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (Integer.parseInt(maze[i][j]) == 0)
{
q.add(new Pos2(i, j, 0));
}
}
}
Bfs(q,R,C,maze);
}
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
visited[i][j] = false;
}
}
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (Integer.parseInt(maze[i][j]) >= 1 && !visited[i][j]) {
q.add(new Pos2(i, j, 0));
visited[i][j] = true;
count = count + Bfs2(q, R, C,maze, visited);
}
}
}
time = time + 1;
if (count >= 2) {
System.out.println(time);
break;
}
if (count <= 0) {
System.out.println(0);
break;
}
}
}
}