알고리즘
[Java] 백준 15653번 구슬 탈출 4
J3SUNG
2023. 2. 7. 20:33
728x90
https://j3sung.tistory.com/863
[Java] 백준 13460 구슬 탈출 2
직사각형 보드를 상하좌우로 기울여서 10번안에 빨간색구슬을 탈출 시켜야 합니다. 직사각형의 최대 크기극 10*10이며 상하좌우, 10번으로 값이 적으므로 브루트포스 알고리즘으로 문제를 접근하
j3sung.tistory.com
구슬 탈출2에서 조건을 조금 수정해서 제출했습니다.
다른점은 10번의 이동안에 성공을 할 수 있는지 확인하는 문제에서
몇번만에 성공시킬 수 있는지 찾는 문제였습니다.
visit[10][10][10][10] 4차원 배열을 이용해서
빨강구슬의 좌표와 파랑구슬의 좌표가 방문한적 있는 경우에 대해서 중복 방문을 막아줬습니다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int n;
static int m;
static int ans = 987654321;
static int[][] map;
static int[] arr = new int[10];
static Queue<Marble> q;
static boolean end = false;
static boolean[][][][] visit = new boolean[10][10][10][10];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
map = new int[n][m];
q = new LinkedList<Marble>();
char c;
int ry = 0, rx = 0;
int by = 0, bx = 0;
Marble mar;
for(int i=0; i<n; ++i) {
String s = br.readLine();
for(int j=0; j<m; ++j) {
c = s.charAt(j);
switch(c) {
case '#':
map[i][j] = 0;
break;
case '.':
map[i][j] = 1;
break;
case 'B':
by = i;
bx = j;
map[i][j] = 1;
break;
case 'R':
ry = i;
rx = j;
map[i][j] = 1;
break;
case 'O':
map[i][j] = 2;
break;
}
}
}
mar = new Marble(by, bx, ry, rx, 0);
q.add(mar);
while(!q.isEmpty()) {
mar = q.poll();
for(int i=0; i<4; ++i) {
moveMarble(i, mar);
if(end) {
System.out.println(ans);
return;
}
}
}
System.out.println("-1");
}
static void moveMarble(int d, Marble mar) {
int[] dy = {0, 1, 0, -1};
int[] dx = {1, 0, -1, 0};
boolean chk = false;
boolean redSuc = false;
boolean useChk = false;
Marble nMar = new Marble(mar.by, mar.bx, mar.ry, mar.rx, mar.time+1);
if(nMar.by < nMar.ry) { //파랑이 빨강보다 왼쪽 또는 위쪽
chk = true;
} else if (nMar.by == nMar.ry && nMar.bx < nMar.rx) {
chk = true;
}
if((!chk && (d == 0 || d == 1)) || (chk && (d == 2 || d == 3))) { // 파랑구슬부터 이동
while(true) {
int nextBY = nMar.by + dy[d];
int nextBX = nMar.bx + dx[d];
int nextRY = nMar.ry + dy[d];
int nextRX = nMar.rx + dx[d];
boolean moveChk = false;
if(map[nextBY][nextBX] == 2) { // 구멍
return;
}
if(map[nextBY][nextBX] == 1) { // 빈 공간
nMar.by = nextBY;
nMar.bx = nextBX;
moveChk = true;
useChk = true;
}
if(map[nextRY][nextRX] == 2) { // 구멍
ans = Math.min(ans, nMar.time);
end = true;
return;
}
if(map[nextRY][nextRX] == 1 && !(nMar.by == nextRY && nMar.bx == nextRX)) { // 빈 공간
nMar.ry = nextRY;
nMar.rx = nextRX;
moveChk = true;
useChk = true;
}
if(!moveChk) {
if(!useChk) {
return;
}
if(!visit[nMar.by][nMar.bx][nMar.ry][nMar.rx]) {
visit[nMar.by][nMar.bx][nMar.ry][nMar.rx] = true;
q.add(nMar);
}
return;
}
}
} else if ((chk && (d == 0 || d == 1)) || (!chk && (d == 2 || d == 3))) {
while(true) {
int nextBY = nMar.by + dy[d];
int nextBX = nMar.bx + dx[d];
int nextRY = nMar.ry + dy[d];
int nextRX = nMar.rx + dx[d];
boolean moveChk = false;
if(map[nextRY][nextRX] == 2) { // 구멍
redSuc = true;
}
if(map[nextRY][nextRX] == 1) { // 빈 공간
nMar.ry = nextRY;
nMar.rx = nextRX;
moveChk = true;
useChk = true;
}
if(map[nextBY][nextBX] == 2) { // 구멍
return;
}
if(map[nextBY][nextBX] == 1 && (!(nextBY == nMar.ry && nextBX == nMar.rx) || redSuc)) { // 빈 공간
nMar.by = nextBY;
nMar.bx = nextBX;
moveChk = true;
useChk = true;
}
if(redSuc && !moveChk) { //R D L U
ans = Math.min(ans, nMar.time);
end = true;
return;
}
if(!moveChk) {
if(!useChk) {
return;
}
if(!visit[nMar.by][nMar.bx][nMar.ry][nMar.rx]) {
visit[nMar.by][nMar.bx][nMar.ry][nMar.rx] = true;
q.add(nMar);
}
return;
}
}
}
}
static class Marble {
public int by, bx, ry, rx, time;
Marble(int by, int bx, int ry, int rx, int time){
this.by = by;
this.bx = bx;
this.ry = ry;
this.rx = rx;
this.time = time;
}
}
}