문제 설명
Ricochet Robot이라는 보드 게임이 있습니다.
이 보드게임은 격자 모양의 게임판에 자신의 말을 옮기고 시작 위치에서 목표 위치까지 갈 수 있는 최소 횟수를 알려주는 게임입니다.
이 게임에서 말은 위, 아래, 왼쪽 또는 오른쪽의 네 방향 중 하나로 이동하고 장애물에 부딪히거나 보드의 다른 쪽 끝이 될 때까지 미끄러지는 것을 한 이동으로 간주합니다.
다음은 보드 게임 보드의 예입니다.
...D..R
.D.G...
....D.D
D....D.
..D....
“.” 빈 공간의 경우 “R”은 로봇의 초기 위치, “D”는 장애물의 위치, “G”는 목표 지점입니다.
위의 예에서 “R” 위치에서 아래, 왼쪽, 위, 왼쪽, 아래, 오른쪽, 위 순서로 이동하면 가장 작은 동작 중 하나인 7 동작에서 “G” 위치에서 멈출 수 있습니다.
게임 보드의 상태를 나타내는 문자열 배열 판자가 주어졌을 때 말이 목표 위치에 도달하는 데 필요한 최소 이동 수를 반환하는 솔루션 함수를 완성하십시오. 목표 위치에 도달할 수 없으면 -1을 반환합니다.
제한
- 3 ≤ 플레이트 길이 ≤ 100
- 3 ≤ 패널 요소 길이 ≤ 100
- 보드 요소는 모두 같은 길이입니다.
- 문자열은 “.”, “D”, “R” 및 “G”로만 구성되며 각각 빈 공간, 장애물, 로봇의 초기 위치 및 목표 지점을 나타냅니다.
- “R”과 “G”가 한 번 나타납니다.
import java.util.ArrayDeque;
class Solution {
private char()() map;
private boolean()() visited;
private ArrayDeque<Custom> que;
static class Custom {
int x;
int y;
int count;
public Custom(int x, int y, int count) {
this.x = x;
this.y = y;
this.count = count;
}
}
public Custom goLeft(Custom custom) {
int x = custom.x;
int y = custom.y;
while (y != 0 && map(x)(y - 1) != 'D') {
y--;
}
return y != custom.y ? new Custom(x, y, custom.count + 1) : null;
}
public Custom goRight(Custom custom) {
int x = custom.x;
int y = custom.y;
while (y != map(0).length - 1 && map(x)(y + 1) != 'D') {
y++;
}
return y != custom.y ? new Custom(x, y, custom.count + 1) : null;
}
public Custom goUp(Custom custom) {
int x = custom.x;
int y = custom.y;
while (x != 0 && map(x - 1)(y) != 'D') {
x--;
}
return x != custom.x ? new Custom(x, y, custom.count + 1) : null;
}
public Custom goDown(Custom custom) {
int x = custom.x;
int y = custom.y;
while (x != map.length - 1 && (map(x + 1)(y) != 'D')) {
x++;
}
return x != custom.x ? new Custom(x, y, custom.count +1) : null;
}
public void addQue(Custom end, String way) {
if (end == null) return;
if (!visited(end.x)(end.y)) {
visited(end.x)(end.y) = true;
que.addLast(end);
}
}
public int solution(String() board) {
que = new ArrayDeque<>();
map = new char(board.length)(board(0).length());
visited = new boolean(board.length)(board(0).length());
int x = 0, y = 0;
for (int i = 0; i < board.length; i++) {
map(i) = board(i).toCharArray();
if (board(i).contains("R")) {
x = i;
y = board(i).indexOf('R');
}
}
que.addLast(new Custom(x, y, 0));
visited(x)(y) = true;
int result = Integer.MAX_VALUE;
while (!que.isEmpty()) {
Custom custom = que.pollFirst();
if (map(custom.x)(custom.y) == 'G') {
result = Math.min(result, custom.count);
}
addQue(goLeft(custom), "L");
addQue(goRight(custom), "R");
addQue(goUp(custom), "U");
addQue(goDown(custom), "D");
}
return result == Integer.MAX_VALUE ? -1 : result;
}
}
출처: 프로그래머 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges