알고리즘/문제풀이
[소프티어] 나무 섭지 풀이에 관하여.java
지화자_
2024. 3. 20. 22:27
https://softeer.ai/practice/7726
Softeer - 현대자동차그룹 SW인재확보플랫폼
softeer.ai
✍문제 해결 핵심 전략탈출 여부의 요인 정확히 분석하기
- 남우가 탈출하기 위해서는 유령에게 잡히지 않고 탈출구를 찾아가야 합니다.
- 남우와 유령 사이의 관계 명확히 파악하기 (벽 넘기의 유무)
🔍'유령에게 잡히지 않는다'
▶ 유령보다 탈출구에 더 빨리 도착해야한다.
🔍'탈출구를 찾아간다.'
▶ 탐색을 통해 탈출구에 도달할 수 있는가?.
🔍'벽을 넘을 수 있다.'를 위의 내용과 연관시키면
▶ 벽의 유무를 고려한 뒤 남우가 최단거리로 출구에 가야 한다.
한 줄 요약
유령과 탈출구 사이 거리, 남우와 탈출구 사이 거리 (남우는 벽을 고려)
비교를 통해 탈출의 유무를 확인할 수 있다.
👨💻Code 구현
import java.util.*;
public class Softeer_나무섭지 {
static int Dr, Dc, Nr, Nc, Wr, Wc, ghost_num, n, m, Min_distanceDoortoGhost,Min_distanceDoortoNam, distanceDoortoNam;
static int[] dr = {0, -1, 0, 1};
static int[] dc = {-1, 0, 1, 0};
static int[][] visited ;
static char[][] maze;
static List<int[]> ghostPos = new ArrayList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt(); //행
m = sc.nextInt(); //열
maze = new char[n][m];
visited = new int[n][m];
ghost_num = 0;
Dr = 0;Dc = 0;
Nr = 0;Nc = 0;
Wr = 0;Wc = 0;
Min_distanceDoortoGhost = Integer.MAX_VALUE;
Min_distanceDoortoNam = Integer.MAX_VALUE ;
for (int i = 0; i < n; i++) {
String str = sc.next();
for (int j = 0; j < m; j++) {
maze[i][j] = str.charAt(j);
if (maze[i][j] == 'G') {
int[] arr = new int[2];
arr[0] = i;
arr[1] = j;
ghostPos.add(arr);
ghost_num++;
} else if (maze[i][j] == 'D') {
Dr = i;
Dc = j;
} else if (maze[i][j] == 'N') {
Nr = i;
Nc = j;
} else if (maze[i][j] == '#') {
Wr = i;
Wc = j;
}
}
}// idx 미리 찾기
//유령과 문사이 최소거리 구하기
for (int ghost = 0; ghost < ghost_num; ghost++) {
int[] arr = ghostPos.get(ghost);
int sum = Math.abs(Dr - arr[0]) + Math.abs(Dc - arr[1]);
if (sum < Min_distanceDoortoGhost)
Min_distanceDoortoGhost = sum;
}
if (cal_distanceDoortoNam(Nr, Nc) > 0 && cal_distanceDoortoNam(Nr, Nc) < Min_distanceDoortoGhost)
System.out.println("Yes");
else System.out.println("No");
}
public static int cal_distanceDoortoNam( int Nr, int Nc) { //BFS로 칸마다 걸리는 이동 거리 확인하기
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{Nr,Nc});
visited[Nr][Nc] = 0;
while (!q.isEmpty()){
int[] currentNam = q.poll();
int curR = currentNam[0];
int curC = currentNam[1];
for(int i =0; i<4 ; i++){
int nR = curR + dr[i];
int nC = curC + dc[i];
if(nR >= n || nR < 0 || nC >= m || nC < 0 || maze[nR][nC] == '#') continue; //경계조건 or 벽 발견
if(visited[nR][nC] == 0 ){
visited[nR][nC] = visited[curR][curC] + 1 ; //이동한 거리를 칸마다 갱신한다.
q.add(new int[]{nR,nC});
}
}
}
return visited[Dr][Dc];
}
}