[๋ฐฑ์ค] ๐ฅ 1938 ํต๋๋ฌด ์ฎ๊ธฐ๊ธฐ
๐ ๋์ด๋
๐ฅ Gold 2
๐ ๋ฌธ์
https://www.acmicpc.net/problem/1938
๐ ํ์ด
์ต๊ทผ์ ํผ ๊ณจ๋ ๋ฌธ์ ์ค์ ๊ฐ์ฅ ๋์ด๋๊ฐ ๋์ ๋ฌด๋ ค ๊ณจ๋ 2์ง๋ฆฌ ๋ฌธ์ ์๋ค.
์ฒ์ ๋ฌธ์ ๋ฅผ ๋ณด์ ๋ ์๊ฐ์ BFS
๋ก ํ ๋ ํต๋๋ฌด ์ค์ฌ์ ๊ธฐ์ค์ผ๋ก ๊ฐ๋ก, ์ธ๋ก๋ฅผ ๋๋ ์ ๊ตฌํํ์๋ ์๊ฐ์ด์๋ค.
๊ทธ๋์ ํต๋๋ฌด๋ฅผ ์ ์ฅํ pos
๋ผ๋ ์ด๋ฆ์ class๋ฅผ ๋ง๋ค๊ณ , ๊ทธ ์์ r
, c
, isVertical
์ด๋ผ๋ ๋ณ์๋ค์ ๋ฃ์ด์ฃผ์๋ค.
๊ทธ๋๊ณ field
๋ฅผ ๊ตฌ์ฑํ tile
์ด๋ผ๋ ๊ฐ์ฒด์ Vertical
๊ฐ๊ณผ, Horizontal
๊ฐ์ ์ ์ฅํ ๋ณ์๋ฅผ ๋ง๋ค์ด ์ฃผ์๋ค.
์ผ๋ฐ์ ์ธ BFS
์ ๋ค๋ฅด๊ฒ ์ด๋ํ๋ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉํฅ๊ณผ ํ์ฌ ํต๋๋ฌด๊ฐ ์ธ๋ก, ๊ฐ๋ก์ธ์ง์ ๋ฐ๋ผ์ ์ด๋ ๋ฐฉ์์ด ๋ค๋ฅด๋ฏ๋ก DR, DC
๋ฅผ ์ ์ธํ๊ณ , ์ฌ๋ฌ๊ฐ์ง ๋ฐฉํฅ ์์๋ฐฐ์ด์ ๋ง๋ค์ด์ฃผ์๋ค.
์ดํ BFS
๋ฅผ ํตํด ๊ตฌํํ ์ฝ๋์ด๋ค.
๐ Code
package BOJ.BFS;
import java.io.*;
import java.util.*;
public class N1938 {
static class pos {
int r;
int c;
boolean isVertical;
public pos(int r, int c, boolean isVertical) {
this.r = r;
this.c = c;
this.isVertical = isVertical;
}
}
static class tile {
int Vertical;
int Horizontal;
public tile(int state) {
this.Vertical = state;
this.Horizontal = state;
}
}
static Queue<pos> q;
static tile[][] field;
static final int startPoint = 0;
static final int notvisited = 1000002;
static final int tree = -3;
static final int[] VLDR = {-1, 0, 1};
static final int[] VLDC = {-1, -1, -1};
static final int[] VUDR = {-2};
static final int[] VUDC = {0};
static final int[] HLDR = {0};
static final int[] HLDC = {-2};
static final int[] HUDR = {-1, -1, -1};
static final int[] HUDC = {-1, 0, 1};
static final int[] ALLDR = {-1, -1, 0, 1, 1, 1, 0, -1};
static final int[] ALLDC = {0, 1, 1, 1, 0, -1, -1, -1};
static int N;
static int flag;
static final int CantGoGoal = 1000003;
static boolean goalPoint;
static int[] goalPointcoor;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
field = new tile[N][N];
q = new LinkedList<>();
boolean isVertical;
int[][] start = new int[3][2];
int[][] end = new int[3][2];
int flag1 = 0;
int flag2 = 0;
for (int i = 0; i < N; i++) {
String str = br.readLine();
for (int j = 0; j < N; j++) {
if (str.charAt(j) == '0') {
field[i][j] = new tile(notvisited);
} else if (str.charAt(j) == '1') {
field[i][j] = new tile(tree);
} else if (str.charAt(j) == 'B') {
start[flag1] = new int[]{i, j};
field[i][j] = new tile(notvisited);
flag1 += 1;
} else {
end[flag2] = new int[]{i, j};
field[i][j] = new tile(notvisited);
flag2 += 1;
}
}
}
field[start[1][0]][start[1][1]] = new tile(startPoint);
if (start[0][0] != start[2][0]) {
q.add(new pos(start[1][0], start[1][1], true));
} else {
q.add(new pos(start[1][0], start[1][1], false));
}
goalPointcoor = new int[]{end[1][0], end[1][1]};
if (end[0][0] != end[2][0]) {
goalPoint = true;
} else {
goalPoint = false;
}
BFS();
}
static void BFS() {
//ShowAll();
flag = CantGoGoal;
while (!q.isEmpty()) {
pos cur = q.poll();
if (cur.isVertical) {
for (int i = 0; i < 5; i++) {
VerticalLog(cur, i);
}
} else {
for (int i = 0; i < 5; i++) {
HorizonLog(cur, i);
}
}
//ShowAll();
}
if (flag == CantGoGoal) {
System.out.println(0);
} else {
System.out.println(flag);
}
}
static void ShowAll() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i == goalPointcoor[0] && j == goalPointcoor[1]) {
System.out.print(">");
} else {
System.out.print("|");
}
if (field[i][j].Horizontal == notvisited) {
System.out.printf("%2s.", "");
} else {
System.out.printf("%3d", field[i][j].Horizontal);
}
if (field[i][j].Vertical == notvisited) {
System.out.printf("%2s.", "");
} else {
System.out.printf("%3d", field[i][j].Vertical);
}
}
System.out.println();
}
System.out.print("======================");
System.out.println(flag);
}
static boolean VerticalLog(pos cur, int index) {
switch (index) {
case 0:
// Vertical ์ข๋ก ์ด๋
for (int i = 0; i < VLDR.length; i++) {
int nextR = cur.r + VLDR[i];
int nextC = cur.c + VLDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Vertical == tree) {
return false;
}
}
if (cur.r == goalPointcoor[0] && cur.c - 1 == goalPointcoor[1] && goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Vertical + 1);
}
if (field[cur.r][cur.c - 1].Vertical > field[cur.r][cur.c].Vertical + 1) {
field[cur.r][cur.c - 1].Vertical = field[cur.r][cur.c].Vertical + 1;
q.add(new pos(cur.r, cur.c - 1, true));
}
break;
case 1:
// Vertical ์ฐ๋ก ์ด๋
for (int i = 0; i < VLDR.length; i++) {
int nextR = cur.r + VLDR[i];
int nextC = cur.c - VLDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Vertical == tree) {
return false;
}
}
if (cur.r == goalPointcoor[0] && cur.c + 1 == goalPointcoor[1] && goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Vertical + 1);
}
if (field[cur.r][cur.c + 1].Vertical > field[cur.r][cur.c].Vertical + 1) {
field[cur.r][cur.c + 1].Vertical = field[cur.r][cur.c].Vertical + 1;
q.add(new pos(cur.r, cur.c + 1, true));
}
break;
case 2:
// Vertical ์๋๋ก ์ด๋
for (int i = 0; i < VUDR.length; i++) {
int nextR = cur.r - VUDR[i];
int nextC = cur.c + VUDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Vertical == tree) {
return false;
}
}
if (cur.r + 1 == goalPointcoor[0] && cur.c == goalPointcoor[1] && goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Vertical + 1);
}
if (field[cur.r + 1][cur.c].Vertical > field[cur.r][cur.c].Vertical + 1) {
field[cur.r + 1][cur.c].Vertical = field[cur.r][cur.c].Vertical + 1;
q.add(new pos(cur.r + 1, cur.c, true));
}
break;
case 3:
// ์๋ก ์ด๋
for (int i = 0; i < VUDR.length; i++) {
int nextR = cur.r + VUDR[i];
int nextC = cur.c + VUDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Vertical == tree) {
return false;
}
}
if (cur.r - 1 == goalPointcoor[0] && cur.c == goalPointcoor[1] && goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Vertical + 1);
}
if (field[cur.r - 1][cur.c].Vertical > field[cur.r][cur.c].Vertical + 1) {
field[cur.r - 1][cur.c].Vertical = field[cur.r][cur.c].Vertical + 1;
q.add(new pos(cur.r - 1, cur.c, true));
}
break;
case 4:
// ํ์
for (int i = 0; i < ALLDC.length; i++) {
int nextR = cur.r + ALLDR[i];
int nextC = cur.c + ALLDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Vertical == tree) {
return false;
}
}
if (cur.r == goalPointcoor[0] && cur.c == goalPointcoor[1] && !goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Vertical + 1);
}
if (field[cur.r][cur.c].Horizontal > field[cur.r][cur.c].Vertical + 1) {
field[cur.r][cur.c].Horizontal = field[cur.r][cur.c].Vertical + 1;
q.add(new pos(cur.r, cur.c, false));
}
}
return true;
}
static boolean HorizonLog(pos cur, int index) {
switch (index) {
case 0:
// Vertical ์ข๋ก ์ด๋
for (int i = 0; i < HLDR.length; i++) {
int nextR = cur.r + HLDR[i];
int nextC = cur.c + HLDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Horizontal == tree) {
return false;
}
}
if (cur.r == goalPointcoor[0] && cur.c - 1 == goalPointcoor[1] && !goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Horizontal + 1);
}
if (field[cur.r][cur.c - 1].Horizontal > field[cur.r][cur.c].Horizontal + 1) {
field[cur.r][cur.c - 1].Horizontal = field[cur.r][cur.c].Horizontal + 1;
q.add(new pos(cur.r, cur.c - 1, false));
}
break;
case 1:
// Vertical ์ฐ๋ก ์ด๋
for (int i = 0; i < HLDR.length; i++) {
int nextR = cur.r + HLDR[i];
int nextC = cur.c - HLDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Horizontal == tree) {
return false;
}
}
if (cur.r == goalPointcoor[0] && cur.c + 1 == goalPointcoor[1] && !goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Horizontal + 1);
}
if (field[cur.r][cur.c + 1].Horizontal > field[cur.r][cur.c].Horizontal + 1) {
field[cur.r][cur.c + 1].Horizontal = field[cur.r][cur.c].Horizontal + 1;
q.add(new pos(cur.r, cur.c + 1, false));
}
break;
case 2:
// Vertical ์๋๋ก ์ด๋
for (int i = 0; i < HUDR.length; i++) {
int nextR = cur.r - HUDR[i];
int nextC = cur.c + HUDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Horizontal == tree) {
return false;
}
}
if (cur.r + 1 == goalPointcoor[0] && cur.c == goalPointcoor[1] && !goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Horizontal + 1);
}
if (field[cur.r + 1][cur.c].Horizontal > field[cur.r][cur.c].Horizontal + 1) {
field[cur.r + 1][cur.c].Horizontal = field[cur.r][cur.c].Horizontal + 1;
q.add(new pos(cur.r + 1, cur.c, false));
}
break;
case 3:
// ์๋ก ์ด๋
for (int i = 0; i < HUDR.length; i++) {
int nextR = cur.r + HUDR[i];
int nextC = cur.c + HUDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Horizontal == tree) {
return false;
}
}
if (cur.r - 1 == goalPointcoor[0] && cur.c == goalPointcoor[1] && !goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Horizontal + 1);
}
if (field[cur.r - 1][cur.c].Horizontal > field[cur.r][cur.c].Horizontal + 1) {
field[cur.r - 1][cur.c].Horizontal = field[cur.r][cur.c].Horizontal + 1;
q.add(new pos(cur.r - 1, cur.c, false));
}
break;
case 4:
// ํ์
for (int i = 0; i < ALLDC.length; i++) {
int nextR = cur.r + ALLDR[i];
int nextC = cur.c + ALLDC[i];
if (nextR < 0 || nextR >= N || nextC < 0 || nextC >= N || field[nextR][nextC].Horizontal == tree) {
return false;
}
}
if (cur.r == goalPointcoor[0] && cur.c == goalPointcoor[1] && goalPoint) {
flag = Math.min(flag, field[cur.r][cur.c].Horizontal + 1);
}
if (field[cur.r][cur.c].Vertical > field[cur.r][cur.c].Horizontal + 1) {
field[cur.r][cur.c].Vertical = field[cur.r][cur.c].Horizontal + 1;
q.add(new pos(cur.r, cur.c, true));
}
}
return true;
}
}
package (์ด๋ฆ); ๋ฅผ ๋๊ณ , class ์ด๋ฆ์ Main
์ผ๋ก ๋ณ๊ฒฝํ๋ฉด ๋๋ค.
๐ ์ถ๊ฐ ์์
[Input]
5
00011
BBB00
00011
00000
EEE00
[Output]
3
[Input]
7
0000000
0E00000
0E00BBB
0E01001
0000000
0000001
0100000
[Output]
5
[Input]
7
0000000
0E00000
0E00BBB
0E01001
0000000
0000001
0100000
[Output]
5
๊ฐ์ธ ๊ณต๋ถ ๊ธฐ๋ก์ฉ ๋ธ๋ก๊ทธ์
๋๋ค.
ํ๋ฆฌ๊ฑฐ๋ ์ค๋ฅ๊ฐ ์์ ๊ฒฝ์ฐ ์ ๋ณดํด์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.๐