알고리즘/softeer
나무 섭지
베리영young
2025. 2. 7. 23:14
풀고서도
이렇게 단순한 풀이가 맞다고??? 라고 놀란 문제..
import java.io.*;
import java.util.*;
public class Main {
static int n, m ,namwuX,namwuY, goalX, goalY, minGhostLen=Integer.MAX_VALUE;
static char[][] map;
static List<int[]> ghosts = new ArrayList<>();
static int[] dx = {-1,1,0,0};
static int[] dy = {0,0,-1,1};
public static void main(String[] args) {
init();
if(exit() < minGhostLen) System.out.println("Yes");
else System.out.println("No");
}
public static int exit() {
int[][] dp = new int[n][m];
for(int i=0; i<n; i++) Arrays.fill(dp[i], n*m+1);
Queue<int[]> q = new PriorityQueue<>((a,b) -> a[2] - b[2]);
q.add(new int[] {namwuX, namwuY, 0});
dp[namwuX][namwuY] = 0;
while(!q.isEmpty()) {
int[] p = q.poll();
if(p[0] == goalX && p[1] == goalY) {
return p[2];
}
for(int d=0; d<4; d++) {
int nx = p[0] + dx[d];
int ny = p[1] + dy[d];
if(inMap(nx, ny) && map[nx][ny] != '#' && dp[nx][ny] > p[2] + 1) {
dp[nx][ny] = p[2] + 1;
q.add(new int[] {nx, ny, p[2]+1});
}
}
}
///////
return Integer.MAX_VALUE;
}
public static void init() {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
map = new char[n][m];
for(int i=0; i<n; i++) {
String s = sc.next();
for(int j=0; j<m; j++) {
if('N' == s.charAt(j)) {
namwuX = i;
namwuY = j;
map[i][j] = '.';
}
else if('G' == s.charAt(j)) {
ghosts.add(new int[] {i, j, 0});
map[i][j] = '.';
}
else {
if('D' == s.charAt(j)) {
goalX = i;
goalY = j;
}
map[i][j] = s.charAt(j);
}
}
}
for(int i=0; i<ghosts.size(); i++) {
int len = Math.abs(goalX - ghosts.get(i)[0]) + Math.abs(goalY - ghosts.get(i)[1]);
ghosts.get(i)[2] = len;
}
if(ghosts.size() > 0) {
Collections.sort(ghosts, (a,b) -> a[2] - b[2]);
minGhostLen = ghosts.get(0)[2];
}
///
}
public static boolean inMap(int x, int y) {
if(x>=0&&x<n && y>=0&&y<m) return true;
return false;
}
}
고스트가 먼저 골에 도착하면, 남우는 통과하지 못한다.
라는 아이디어밖에 떠오르지 않아서, 일단 그거부터 구현해야지~~~ 했다가 그게 정답의 전부였다는....
블로그 보니까 이런 풀이가 맞는 거 같다.
그런데 유령을 bfs 돌리는 코드가 있던데,
유령은 문제에서 주어진 거처럼 벽도 통과한다. 굳이 bfs를 돌리지 않고, x좌표차이 + y좌표차이 하면 더 빠르게 구할 수 있다.