์์ ๋ก ์ด๋ป๊ฒ ๊ตฌํํ๋์ง ํ์ธํด๋ณด๊ฒ ๋ค.
๋จผ์ , ์ด ๋ฌธ์ ๋ ๋น์ฐํ BFS๋ก ์ ๊ทผํด์ผํ๋ค. BFS๋ฅผ ์ํํ ๋, ํ์ ๋ฌด์กฐ๊ฑด J๊ฐ ์ ์ผ ์ฒซ๋ฒ์งธ๋ก ๋ค์ด๊ฐ์, ๋จผ์ BFS ํ์์ ํ๋๋ก ํ๋ค.
๊ทธ๋์ fire ์ด๋ผ๋ ํ์๋ ๋ถ์ ์์น๋ฅผ ๋จผ์ ๋ด๊ณ , bfs์ ์ฌ์ฉํ q๋ผ๋ ํ์๋ J์์น๋ฅผ ๋ด์๋ค.
๊ทธ๋ฆฌ๊ณ , fire์ ๋ด์ ๋ ๋ถ์ ์์น๋ฅผ q์ ๋ด์๋ค.
J๋ BFS ํ์ ๊ณผ์ ์์ [.] ์ธ ๊ฒฝ์ฐ์๋ง ์ด๋ํ ์ ์์ง๋ง, F(๋ถ)์ ๊ฒฝ์ฐ๋ J์ธ ๊ฒฝ์ฐ์๋ ์ด๋ํ ์ ์๋๋ก ๊ตฌํํ์๋ค.
์ ๊ทธ๋ฆผ์ฒ๋ผ, J ์๊น์ง F๊ฐ ๋ค๊ฐ์์ง๋ง, J๊ฐ ์์ง์ผ ํด์ด๋ฏ๋ก ํ์ถํ ์ ์๋ค.
์ ๊ฒฝ์ฐ์๋ J๊ฐ ๊ฒฝ๊ณ์ ๊น์ง ๋๋ฌํ์ง๋ง, F๊ฐ ์์ง์ผ ํด์ด ์งํ๋๋ฉด, ํ์ถํ ์ ์๊ฒ ๋๋ค. ๋ฐ๋ผ์ ์ด ๊ฒฝ์ฐ๋ฅผ ์ผ๋ํด๋๊ณ ๊ตฌํ์ ํด์ผํ๋ค. ( ์ด ๋ฐ๋ก ๋๋ฌธ์ ๊ฒ๋ ๊ณ ์ํ๋ค..)
ํญ์ ๋ถ๋ณด๋ค J๊ฐ ๋จผ์ ์์ง์ด๋๋ก ํ์ ๋ด์๊ธฐ ๋๋ฌธ์, J๊ฐ ๊ฒฝ๊ณ์ ์ ๋๋ฌํ์ ์์ ์ ๋ฐ๋ก ์ธ์ ํ ์ขํ์ F๊ฐ ์์ผ๋ฉด 100% ํ์ถํ ์ ์์์ ์ ์ ์๊ธฐ ๋๋ฌธ์, ๋ฉ์๋๋ฅผ ํ๋ ์ ์ํด์ ์ฒดํฌํ๋๋ก ๊ตฌํํ์๋ค.
ํ์ J ๋จผ์ ๋ด๊ณ , ํ์ถ ์กฐ๊ฑด๋ง ์ ์ค์ ํ๋ฉด ํฌ๊ฒ ์ด๋ ค์ด ๋ฌธ์ ๊ฐ ์๋ ๊ฒ์ด๋ค!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
static int row;
static int column;
static char[][] map;
static int[][] time;
static int[] dr = {1, -1, 0, 0};
static int[] dc = {0, 0, 1, -1};
static boolean isEscape;
static int ans;
static Queue<int[]> q = new LinkedList<>();
static Queue<int[]> fire = new LinkedList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
row = Integer.valueOf(input[0]);
column = Integer.valueOf(input[1]);
map = new char[row][column];
time = new int[row][column];
isEscape = false;
for (int i = 0; i < row; i++) {
String info = br.readLine();
for (int j = 0; j < column; j++) {
map[i][j] = info.charAt(j);
if (map[i][j] == 'J') {
time[i][j] = 1;
// ์ฒ์ ๋ฐฐ์น๋ถํฐ ๊ฒฝ๊ณ์ ์ ์๋ ๊ฒฝ์ฐ, 1๋ถ์ผ๋ก ๋ฐ๋ก ํ์ถ ํ ์ ์๋ค.
if (i == 0 || i == row - 1 || j == 0 || j == column - 1) {
System.out.println(1);
return;
}
q.offer(new int[]{i, j});
}
if (map[i][j] == 'F') {
fire.offer(new int[]{i, j});
}
}
}
// fire ์ ๋ด์๋ ์์น ์ ๋ณด๋ฅผ q์ ๋ชจ์๋ค.
while(!fire.isEmpty()){
q.offer(fire.poll());
}
bfs();
// bfs ์ดํ, ํ์ถ ๋ถ๊ฐ๋ฅ ํ๋จ์ด๋ฉด IMPOSSIBLE ์ถ๋ ฅ
if (!isEscape) {
System.out.println("IMPOSSIBLE");
} else {
System.out.println(ans);
}
}
static boolean checkNearFire(int r, int c) {
// ๊ฒฝ๊ณ์ ์ ๋๋ฌํ์ ๋ ์ธ์ ํ ๊ณณ์ ๋ถ์ด ์๋์ง ํ์ธ
for (int i = 0; i <= 3; i++) {
int checkR = r + dr[i];
int checkC = c + dc[i];
if ((0 <= checkR && checkR < row) && (0 <= checkC && checkC < column)) {
if (map[checkR][checkC] == 'F') {
return true;
}
}
}
return false;
}
static void bfs() {
while (!q.isEmpty()) {
int[] point = q.poll();
int r = point[0];
int c = point[1];
for (int i = 0; i <= 3; i++) {
int nr = r + dr[i];
int nc = c + dc[i];
if ((0 <= nr && nr < row) && (0 <= nc && nc < column)) {
if (map[r][c] == 'J' && map[nr][nc] == '.') {
time[nr][nc] = time[r][c] + 1;
map[nr][nc] = 'J';
q.offer(new int[]{nr, nc});
if ((nr == 0 || nr == row - 1 || nc == 0 || nc == column - 1)) {
ans = time[nr][nc];
if (checkNearFire(nr, nc)) {
return;
}
isEscape = true;
return;
}
} else if (map[r][c] == 'F' && (map[nr][nc] == '.' || map[nr][nc] == 'J')) {
map[nr][nc] = 'F';
q.offer(new int[]{nr, nc});
}
}
}
}
}
}