0. 개요
BFS 문제입니다.
두 번의 BFS를 통해 이 문제를 해결할 수 있습니다.
- 유령이 시간 내에 갈 수 있는 위치
- 남우 탈출
https://softeer.ai/practice/7726
1. 유령이 시간 내에 갈 수 있는 위치
각 유령의 초기 위치를 큐에 저장해서, 각 위치에 얼마만에 유령이 도달할 수 있는지 저장해야 합니다.
문제의 1번 테스트 케이스를 그림으로 표현하면 아래와 같습니다.
유령의 거리 배열을 저장하게 된다면 아래 그림처럼 나타낼 수 있습니다.
유령은 벽을 통과할 수 있다는 점을 조심해야 합니다.
2. 남우 탈출
유령의 거리 배열을 구했으니, 남우를 탈출시키면 됩니다.
남우를 탈출 할 때 벽인지, 유령보다 빠르게 특정 위치에 갈 수 있는지 고려하면 됩니다.
주의해야할 점은 탈출과 동시에 유령을 만나면 안된다는 점입니다.
유령 거리 배열에서 (0, 5)를 보시면 6으로 저장되어 있습니다.
즉, 6턴 만에 남우가 해당 위치로 도착하더라도 탈락해야 합니다.
[구현 코드]
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
private static final int[] DX = {-1, 1, 0, 0};
private static final int[] DY = {0, 0, -1, 1};
private static final int MAX = 987_654_321;
private static char[][] map;
private static Point nam, destination;
private static int n, m;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stz = new StringTokenizer(br.readLine());
n = Integer.parseInt(stz.nextToken());
m = Integer.parseInt(stz.nextToken());
map = new char[n][m];
int[][] ghostDis = new int[n][m]; // 유령 거리 배열
Queue<Point> qu = new LinkedList<>();
for(int i=0; i<n; i++){
Arrays.fill(ghostDis[i], MAX);
}
for(int i=0; i<n; i++){
char[] chrs = br.readLine().toCharArray();
for(int j=0; j<m; j++){
map[i][j] = chrs[j];
if(map[i][j] == 'G'){ // 유령 위치 저장
qu.add(new Point(i, j));
ghostDis[i][j] = 0;
}else if(map[i][j] == 'N'){
nam = new Point(i, j);
}else if(map[i][j] == 'D'){
destination = new Point(i, j);
}
}
}
ghostDis(qu, ghostDis);
System.out.print(nam(ghostDis));
br.close();
}
private static String nam(int[][] ghostDis) {
Queue<Point> qu = new LinkedList<>();
int[][] dis = new int[n][m];
qu.add(nam);
for(int i=0; i<n; i++){
Arrays.fill(dis[i], MAX);
}
dis[nam.x][nam.y] = 0;
while (!qu.isEmpty()){
Point cn = qu.poll();
if(cn.x == destination.x && cn.y == destination.y){
return "Yes";
}
for(int d = 0; d<DX.length; d++){
int nx = cn.x + DX[d];
int ny = cn.y + DY[d];
if(isOutOfRange(nx, ny) ||
map[nx][ny] == '#' ||
ghostDis[nx][ny] <= dis[cn.x][cn.y] + 1 ||
dis[nx][ny] <= dis[cn.x][cn.y] +1) continue;
dis[nx][ny] = dis[cn.x][cn.y] + 1;
qu.add(new Point(nx, ny));
}
}
return "No";
}
// 유령이 각 시간마다 갈 수 있는 위치
private static void ghostDis(Queue<Point> qu, int[][] dis) {
while (!qu.isEmpty()){
Point cn = qu.poll();
for(int d = 0; d<DX.length; d++){
int nx = cn.x + DX[d];
int ny = cn.y + DY[d];
if(isOutOfRange(nx, ny) || dis[nx][ny] <= dis[cn.x][cn.y] + 1) continue;
dis[nx][ny] = dis[cn.x][cn.y] + 1;
qu.add(new Point(nx, ny));
}
}
}
private static boolean isOutOfRange(int x, int y){
return x < 0 || y < 0 || x >= n || y >= m;
}
private static class Point{
int x, y;
Point(int x, int y){
this.x = x;
this.y = y;
}
}
}
'알고리즘' 카테고리의 다른 글
프로그래머스 - 퍼즐 게임 챌린지 (0) | 2024.09.11 |
---|---|
소프티어 - 효도 여행 (Java) (0) | 2024.06.26 |
코드 트리 - 마법의 숲 탐색(Java) (0) | 2024.06.09 |
백준 - 3197 백조의 호수(Java) (0) | 2023.09.30 |
프로그래머스 - 상담원 인원 (Java) (4) | 2023.08.08 |