[백준] 13460번 구슬 탈출2 - Java/자바
문제
입력
첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 ‘.
’, ‘#
’, ‘O
’, ‘R
’, ‘B
’ 로 이루어져 있다. ‘.
‘은 빈 칸을 의미하고, ‘#
‘은 공이 이동할 수 없는 장애물 또는 벽을 의미하며, ‘O
‘는 구멍의 위치를 의미한다. ‘R
‘은 빨간 구슬의 위치, ‘B
‘는 파란 구슬의 위치이다.
입력되는 모든 보드의 가장자리에는 모두 ‘#
‘이 있다. 구멍의 개수는 한 개 이며, 빨간 구슬과 파란 구슬은 항상 1개가 주어진다.
출력
최소 몇 번 만에 빨간 구슬을 구멍을 통해 빼낼 수 있는지 출력한다. 만약, 10번 이하로 움직여서 빨간 구슬을 구멍을 통해 빼낼 수 없으면 -1을 출력한다.
접근방법
문제에서 주의해야할 점은 빨간구슬과 파란구슬을 같이 움직여줘야 한다. 두 구슬 모두 벽이 나올 때까지 이동하고, 서로 만나면 구슬의 원래 위치와 이동해온 방향에 따라서 두 구슬 중에 하나의 위치를 한 칸 이전으로 옮겨주었다. 만약에 이동하면서 구멍을 빠져나오게 된다면 빨간구슬만 나올 경우에만 리턴해주었다.
풀이
import java.io.*;
import java.util.*;
class Coo {
int rx, ry, bx, by, cnt;
Coo(int rx, int ry, int bx, int by, int cnt) {
this.rx = rx;
this.ry = ry;
this.bx = bx;
this.by = by;
this.cnt = cnt;
}
}
public class Main {
static int N, M;
static char[][] map;
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
static boolean[][][][] visit;
static Coo r, b;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new char[N][M];
visit = new boolean[N][M][N][M];
for(int i = 0; i < N; i++) {
String str = br.readLine();
for(int j = 0; j < M; j++) {
map[i][j] = str.charAt(j);
if(map[i][j] == 'R')
r = new Coo(i, j, 0, 0, 0);
else if(map[i][j] == 'B')
b = new Coo(0, 0, i, j, 0);
}
}
System.out.println(bfs());
}
public static int bfs() {
Queue<Coo> q = new LinkedList<>();
q.add(new Coo(r.rx, r.ry, b.bx, b.by, 1));
visit[r.rx][r.ry][b.bx][b.by] = true;
while(!q.isEmpty()) {
Coo temp = q.poll();
int rx = temp.rx;
int ry = temp.ry;
int bx = temp.bx;
int by = temp.by;
int count = temp.cnt;
if(count > 10) {
return -1;
}
for(int i = 0; i < 4; i++) {
int rnx = rx;
int rny = ry;
int bnx = bx;
int bny = by;
boolean gr = false;
boolean gb = false;
while(map[rnx + dx[i]][rny + dy[i]] != '#') {
rnx += dx[i];
rny += dy[i];
if(map[rnx][rny] == 'O') {
gr = true;
break;
}
}
while(map[bnx + dx[i]][bny + dy[i]] != '#') {
bnx += dx[i];
bny += dy[i];
if(map[bnx][bny] == 'O') {
gb = true;
break;
}
}
if(gb) continue;
if(gr) return count;
if(rnx == bnx && rny == bny) {
if(i == 0) {
if(rx < bx) bnx++;
else rnx++;
}
else if(i == 1) {
if(rx < bx) rnx--;
else bnx--;
}
else if(i == 2) {
if(ry < by) bny++;
else rny++;
}
else {
if(ry < by) rny--;
else bny--;
}
}
if(!visit[rnx][rny][bnx][bny]) {
q.add(new Coo(rnx, rny, bnx, bny, count + 1));
visit[rnx][rny][bnx][bny] = true;
}
}
}
return -1;
}
}
댓글남기기