문제에서 요구하는 것은 세 가지 입니다. 죽지 않고(조건1) 최단 거리로(조건2) 안전지대에 도착(조건2) 할 수 있는지 여부를 체크하는 것입니다. 코드 상에는 움직이는 사람의 체력을 저장하여 죽지 않고 이동할 수 있는 경로를 탐색해야 하며 안전지대에 도착하는 최단 경로의 거리를 계산해야합니다.
모든 경로를 완전 탐색하는 코드로 구현하였다가 현재 이동거리가 안전지대까지의 최단 거리보다 작을 경우 이동하는 것으로 변경하여 연산 횟수를 감소시켰습니다.
이전 코드 시간 788ms -> 코드 수정 후 168ms
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Main {
static int d;
static int[][] point;
static boolean[] visited;
static int count;
static int min;
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 h = Integer.parseInt(st.nextToken());
d = Integer.parseInt(st.nextToken());
char[][] map = new char[n][n];
count=0;
// 맵 입력을 받음과 동시에 우산의 개수를 센다.
for(int i = 0; i < n; i++) {
map[i] = br.readLine().toCharArray();
for(int j = 0; j < n; j++) {
if(map[i][j]=='U') count++;
}
}
int[] s = new int[2]; // 시작점
point = new int[count+1][2]; // 우산과 안전지대 위치 저장
visited = new boolean[count+1]; // 방문 처리 배열
min = Integer.MAX_VALUE; // 최단 경로 저장
int index = 0;
// 각 지점 S, U, E 의 위치를 저장한다.
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(map[i][j]=='S')
s = new int[] {i,j};
if(map[i][j]=='U')
point[index++] = new int[] {i,j};
if(map[i][j]=='E')
point[count] = new int[] {i,j};
}
}
// DFS 탐색
dfs(0, h, 0, s[0], s[1]);
// 만약 최단 경로가 처음에 할당해준 Integer.MAX_VALUE값 그대로 일 경우 다시 업데이트
if(min==Integer.MAX_VALUE)
min = -1;
System.out.print(min);
}
// DFS
static void dfs(int distance, int h, int u, int x, int y) {
// 현재 이동거리가 목적지까지 최단 경로보다 작아야 한다.
if(distance < min) {
// 목적지에 도착했을 경우 거리 저장
if(x == point[count][0] && y == point[count][1]) {
min = distance;
}else{
// 방문하지 않은 지점들에 대해 DFS 탐색
for(int i = 0; i <= count; i++ ) {
int temp = Math.abs(x - point[i][0])+Math.abs(y - point[i][1]);
if(!visited[i]&&temp-1 < h+u) {
int z = h; // 플레이어의 체력
// 우산이 이동 중에 파손되거나 쓰고 있지 않을 때 체력 소모
if(u-temp+1 < 0)
z += (u-temp+1);
visited[i] = true;
dfs(distance+temp, z, d-1, point[i][0], point[i][1]);
visited[i] = false;
}
}
}
}
}
}