Algorithm/DP

BOJ#13460 째로탈출 2

밤이2209 2017. 3. 31. 01:34

BOJ#13460 째로탈출 2


* 문제

* 풀이

dp + 탐색문제.
별로 설명할 것이 없습니다. 코드 이해 안가시면 댓글 주세요.


* 나의 코드



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
* BOJ#13460 째로탈출
* https://www.acmicpc.net/problem/13460
*/

public class Main {

// map info
static final int WALL = -1;
static final int BLANK = 0;
static final int HOLE = -10;
static final int LIMIT = 10;

static int N, M;
static int[][] map = new int[11][11];
static int[][][][][] dp = new int[11][11][11][11][11];

// direction
static final int LEFT = 0;
static final int UP = 1;
static final int RIGHT = 2;
static final int DOWN = 3;

// result
static final int NONE = 0;
static final int SUCCESS = 1;
static final int FAIL = 2;

static int ret = NONE;
static final int INF = 100;

public static void main(String[] args) throws IOException {

int rRow = -1, rCol = -1; // 빨간구슬 위치
int bRow = -1, bCol = -1; // 파란구슬 위치

// input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());

N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());

for (int i = 0; i < N; i++) {

String rowInfo = br.readLine();
for (int j = 0; j < M; j++) {

char inputChar = rowInfo.charAt(j);
switch (inputChar) {

case '#':
map[i][j] = WALL;
break;

case '.':
map[i][j] = BLANK;
break;

case 'R':
map[i][j] = BLANK;
rRow = i;
rCol = j;
break;

case 'B':
map[i][j] = BLANK;
bRow = i;
bCol = j;
break;

case 'O':
map[i][j] = HOLE;
break;
}
}
}

// solve
dfs(rRow, rCol, bRow, bCol, 0);

System.out.println(dp[rRow][rCol][bRow][bCol][0] > LIMIT ? -1 : dp[rRow][rCol][bRow][bCol][0]);

} // main

static int dfs(int rRow, int rCol, int bRow, int bCol, int step) {

int temp = INF;

// memoization
if (dp[rRow][rCol][bRow][bCol][step] > 0) {

return dp[rRow][rCol][bRow][bCol][step];
}

// 종료 조건
if (step >= LIMIT) {

return dp[rRow][rCol][bRow][bCol][step] = INF;
}

for (int direction = 0; direction < 4; direction++) {

PointInfo info = action(rRow, rCol, bRow, bCol, direction);

if (ret > 0) {

if (ret == SUCCESS) {

ret = NONE;
dp[info.rRow][info.rCol][info.bRow][info.bCol][step + 1] = step + 1;

return dp[rRow][rCol][bRow][bCol][step] = step + 1;
} else {

ret = NONE;

dp[info.rRow][info.rCol][info.bRow][info.bCol][step + 1] = INF;
continue;
}
}

temp = Math.min(temp, dfs(info.rRow, info.rCol, info.bRow, info.bCol, step + 1));
}

return dp[rRow][rCol][bRow][bCol][step] = temp;
}

static PointInfo action(int rRow, int rCol, int bRow, int bCol, int dir) {

int nBlank;
PointInfo initialState = new PointInfo(rRow, rCol, bRow, bCol);

switch (dir) {

case LEFT:

// redBall
while (map[rRow][rCol - 1] != WALL) {

rCol--;

if (map[rRow][rCol] == HOLE) {

ret = ret > NONE ? ret : SUCCESS;
break;
}
}

// blueBall
while (map[bRow][bCol - 1] != WALL) {

bCol--;

if (map[bRow][bCol] == HOLE) {

ret = FAIL;
break;
}
}

if (ret == NONE && rRow == bRow && rCol == bCol) {

if (initialState.rCol < initialState.bCol) {

bCol++;
} else {

rCol++;
}
}
break;

case UP:

// redBall
while (map[rRow - 1][rCol] != WALL) {

rRow--;

if (map[rRow][rCol] == HOLE) {

ret = ret > NONE ? ret : SUCCESS;
break;
}
}

// blueBall
while (map[bRow - 1][bCol] != WALL) {

bRow--;

if (map[bRow][bCol] == HOLE) {

ret = FAIL;
break;
}
}

if (ret == NONE && rRow == bRow && rCol == bCol) {

if (initialState.rRow < initialState.bRow) {

bRow++;
} else {

rRow++;
}
}
break;

case RIGHT:

// redBall
while (map[rRow][rCol + 1] != WALL) {

rCol++;

if (map[rRow][rCol] == HOLE) {

ret = ret > NONE ? ret : SUCCESS;
break;
}
}

// blueBall
while (map[bRow][bCol + 1] != WALL) {

bCol++;

if (map[bRow][bCol] == HOLE) {

ret = FAIL;
break;
}
}

if (ret == NONE && rRow == bRow && rCol == bCol) {

if (initialState.rCol < initialState.bCol) {

rCol--;
} else {

bCol--;
}
}
break;

case DOWN:

// redBall
while (map[rRow + 1][rCol] != WALL) {

rRow++;

if (map[rRow][rCol] == HOLE) {

ret = ret > NONE ? ret : SUCCESS;
break;
}
}

// blueBall
while (map[bRow + 1][bCol] != WALL) {

bRow++;

if (map[bRow][bCol] == HOLE) {

ret = FAIL;
break;
}
}

if (ret == NONE && rRow == bRow && rCol == bCol) {

if (initialState.rRow < initialState.bRow) {

rRow--;
} else {

bRow--;
}
}
break;

}

return new PointInfo(rRow, rCol, bRow, bCol);
}
}

class PointInfo {

int rRow, rCol, bRow, bCol;

PointInfo(int rRow, int rCol, int bRow, int bCol) {

this.rRow = rRow;
this.rCol = rCol;
this.bRow = bRow;
this.bCol = bCol;
}
}



'Algorithm > DP' 카테고리의 다른 글

BOJ#13398 연속합2  (1) 2017.04.04
BOJ#1520 내리막 길  (0) 2017.03.31
BOJ#1670 정상 회담2  (0) 2017.03.24
BOJ#2196 로봇 조종하기  (1) 2017.03.17
BOJ#2532 먹이사슬 (Chain)  (0) 2017.02.21