[백준 2842 : JAVA] 집배원 한상덕 / BFS + 투 포인터
문제


풀이
문제를 이해하는데 시간이 좀 걸렸다. 최단 경로에서 고도 차가 아니라, 가장 낮은 고도차(피로도가 가장 적은)를 구하는 문제.
먼저, 입력받은 고도에 대해 중복없이 배열(리스트)에 저장한 후, 정렬한다.
정렬된 고도 값을 담은 1차원 배열에 대해 투 포인터를 잡고, BFS 탐색 조건을 건다.
1) 다음으로 탐색할 땅의 고도가 투 포인터로 잡은 최저 고도보다 크거나 같고, 최고 고도보다 작거나 같다.
위의 탐색 조건으로 탐색을 끝낸 후, 모든 집을 방문했는지 여부를 확인한 다음 고도 차를 저장해 나간다.
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); private static int N, houseNum, startX, startY, ans = 1_000_000; private static char[][] map; private static int[][] heightMap; private static List<Integer> heightList = new ArrayList<>(); private static boolean[][] visited; private static int[] dx = {-1, 1, 0, 0, -1, -1, 1, 1}; private static int[] dy = {0, 0, 1, -1, -1, 1, 1, -1}; static class Node { int x, y; public Node(int x, int y) { this.x = x; this.y = y; } } public static void main(String[] args) throws IOException { N = Integer.parseInt(br.readLine()); heightMap = new int[N][N]; map = new char[N][N]; for (int i = 0; i < N; i++) { String str = br.readLine(); for (int j = 0; j < N; j++) { map[i][j] = str.charAt(j); if (map[i][j] == 'K') { houseNum++; } if (map[i][j] == 'P') { startX = j; startY = i; } } } for (int i = 0; i < N; i++) { StringTokenizer st = new StringTokenizer(br.readLine()); for (int j = 0; j < N; j++) { heightMap[i][j] = Integer.parseInt(st.nextToken()); if (!heightList.contains(heightMap[i][j])) heightList.add(heightMap[i][j]); } } Collections.sort(heightList); bfs(); br.close(); } public static void bfs() { int low = 0, high = 0; while (low < heightList.size()) { visited = new boolean[N][N]; Queue<Node> queue = new LinkedList<>(); int val = heightMap[startY][startX]; if (heightList.get(low) <= val && val <= heightList.get(high)) { visited[startY][startX] = true; queue.add(new Node(startX, startY)); } int count = 0; while (!queue.isEmpty()) { Node cur = queue.poll(); if (map[cur.y][cur.x] == 'K') count++; for (int d = 0; d < 8; d++) { int nx = cur.x + dx[d]; int ny = cur.y + dy[d]; if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue; if (visited[ny][nx]) continue; int nextVal = heightMap[ny][nx]; // 탐색의 조건에 해당한다. // high 고도 - low 고도의 높이 차에 해당하는 땅만 밝아가며 탐색한다는 의미. if (heightList.get(low) <= nextVal && nextVal <= heightList.get(high)) { visited[ny][nx] = true; queue.add(new Node(nx, ny)); } } } if (houseNum == count) { ans = Math.min(ans, heightList.get(high) - heightList.get(low)); low++; } else if (high + 1 < heightList.size()) { high++; } else break; } System.out.println(ans); } }
'Algorithm > Baekjoon' 카테고리의 다른 글
[백준 15684 : JAVA] 사다리 조작 / 백트래킹 (0) | 2020.11.08 |
---|---|
[백준 6549 : JAVA] 히스토그램에서 가장 큰 직사각형 / 세그먼트 트리 +분할정복 (0) | 2020.11.02 |
[백준 2531 : JAVA] 회전 초밥 / 투 포인터 (0) | 2020.10.26 |
[백준 1854 : JAVA] K번째 최단경로 찾기 / 다익스트라 (1) | 2020.10.23 |
[백준 1238 : JAVA] 파티 / 다익스트라 (0) | 2020.10.22 |
댓글
이 글 공유하기
다른 글
-
[백준 15684 : JAVA] 사다리 조작 / 백트래킹
[백준 15684 : JAVA] 사다리 조작 / 백트래킹
2020.11.08 -
[백준 6549 : JAVA] 히스토그램에서 가장 큰 직사각형 / 세그먼트 트리 +분할정복
[백준 6549 : JAVA] 히스토그램에서 가장 큰 직사각형 / 세그먼트 트리 +분할정복
2020.11.02 -
[백준 2531 : JAVA] 회전 초밥 / 투 포인터
[백준 2531 : JAVA] 회전 초밥 / 투 포인터
2020.10.26 -
[백준 1854 : JAVA] K번째 최단경로 찾기 / 다익스트라
[백준 1854 : JAVA] K번째 최단경로 찾기 / 다익스트라
2020.10.23
댓글을 사용할 수 없습니다.