오늘 풀어볼 문제는 ⭐복제 로봇 이라는 문제이다.
[입력]
[출력]
이 문제의 핵심은 우선순위큐를 활용하는 것이다.
해당 문제의 한 가지 특이점은, 로봇이 복제가 된다 라는 점이다. 로봇의 복제는 출발점과 열쇠 위치에서 이루어지는데, 이는 2가지를 시사하고 있다.
- 출발지점에서 4가지 방향(위, 아래, 오른쪽, 왼쪽)으로 로봇을 복제해 출발시킨다.
- 열쇠에 도달했다면, 로봇이 지금까지 이동한 거리를 0으로 초기화 후 4가지 방향으로 출발시켜야 한다.
해당 문제 풀이법은 다음과 같다.
- move [][][] = new int[N+2][N+2][4] 배열 형성. -> 현재 위치 특정 방향에 도달 위한 최소 움직임 기록 위함
- map [][] = new char[N+2][N+2] 배열 형성 -> map 기록 용
- 움직임 순으로 오름차순 정렬된 우선순위 큐
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Info {
int x;
int y;
int dir;
int move;
public Info(int x, int y, int dir, int move) {
this.x=x;
this.y=y;
this.dir=dir;
this.move=move;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int [][][] move = new int[N+2][N+2][4];
char [][] map = new char[N+2][N+2];
int answer = 0;
int dirX[] = {0,0,1,-1};
int dirY[] = {-1,1,0,0};
Queue<Info> queue = new PriorityQueue<>(Comparator.comparingInt((Info o) -> o.move));
Arrays.fill(map[0],'1');
Arrays.fill(map[N+1],'1');
for(int j=0; j<=N+1; j++) {
map[0][j] = '1';
map[N+1][j] = '1';
}
for(int i=0; i<N+2; i++){
for(int j=0; j<N+2; j++){
Arrays.fill(move[i][j], Integer.MAX_VALUE);
}
}
for(int i=1; i<=N; i++){
String line = br.readLine();
for (int j = 1; j <= N; j++) {
map[i][j] = line.charAt(j-1);
if(map[i][j]=='S') {
queue.add(new Info(i,j,0,0));
}
}
}
while (!queue.isEmpty()) {
Info now = queue.poll();
move[now.x][now.y][now.dir]=now.move;
if(map[now.x][now.y]=='K') {
M--;
map[now.x][now.y]='0';
answer+=now.move;
now.move=0;
}
if(M==0) break;
for(int i=0; i<4; i++){
int nextX = now.x+dirX[i];
int nextY = now.y+dirY[i];
if(map[nextX][nextY]=='1') continue;
if(move[nextX][nextY][i] < now.move+1) continue;
queue.add(new Info(nextX, nextY, i, now.move+1));
}
}
System.out.println(M==0 ? answer : -1);
}
}
문제를 다 풀고 내 코드가 너무 시간이 오래 걸려 다시 점검해본 결과, move 배열이 3차원 배열일 이유가 없었다. 2차원 배열로도 더 적은 메모리와 빠른 시간으로 문제를 통과했다.
이런 풀이를 생각하게 된 건 며칠 전에 풀었던 거울설치 문제에서 영감을 받았는데, 거울 설치와 달리 해당 문제는 방향에 대한 고려를 하지 않아도 되었기에, 방향성을 제외해도 충분히 풀 수 있는 것 같다.
