알고리즘/최소신장트리(MST) & 다익스트라

[백준]JAVA - 20926번: 얼음 미로

K.두부 2023. 3. 7. 23:08
반응형

https://www.acmicpc.net/problem/20926

 

20926번: 얼음 미로

탐험가 테라는 얼음 미로에 갇혔다. 얼음 미로의 바닥은 빙판으로 되어 있어 발을 내디디면 바위에 부딪힐 때까지 미끄러진다. 예를 들어, 위 그림에서 테라가 왼쪽 방향으로 이동한다면 중간에

www.acmicpc.net

풀이

포켓몬 얼음동굴이 생각나는 다익스트라 문제.

 

테라, 바위, 구멍, 출구가 char형이라서 int형으로 임의의 값을 줘서 int형 배열로 선언했다.

static int Rock = 100, Hole = -1, Escape = 200, W, H;
for (int i=0; i<H; i++) {
String str = br.readLine();
for (int j=0; j<W; j++) {
int tmp = str.charAt(j);
if (tmp == 'T') {
sx = i;
sy = j;
}
else if (tmp == 'R') map[i][j] = Rock;
else if (tmp == 'H') map[i][j] = Hole;
else if (tmp == 'E') map[i][j] = Escape;
else map[i][j] = tmp - '0';
}
}

 

아래 3가지 조건을 지켜주면서 bfs를 돌리면 된다.

  1. 4방향으로 움직일 수 있고, 중간에 돌이 있다면 멈출 수 없다.
  2. 범위를 벗어나거나 구멍에 빠지면 그대로 떨어진다.
  3. 출구에 도착했을 경우 최단 거리를 비교한다.
while (true) {
nx += dx[d];
ny += dy[d];
if (nx < 0 || ny < 0 || nx >= H || ny >= W) break;
if (map[nx][ny] == Hole) break;
if (map[nx][ny] == Rock) {
nx -= dx[d];
ny -= dy[d];
pq.add(new Pos(nx, ny, sec));
break;
}
if (map[nx][ny] == Escape) {
ans = Math.min(ans, sec);
break;
}
sec += map[nx][ny];
}

 

<최종코드>

import java.io.*;
import java.util.*;
public class Main {
static int Rock = 100, Hole = -1, Escape = 200, W, H;
static int ans = Integer.MAX_VALUE;
static int[] dx = {0, 1, 0, -1};
static int[] dy = {1, 0, -1, 0};
static int[][] map;
public static class Pos implements Comparable<Pos> {
int x, y, sec;
public Pos (int x, int y, int sec) {
this.x = x;
this.y = y;
this.sec = sec;
}
public int compareTo (Pos o) {
return this.sec - o.sec;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
W = Integer.parseInt(st.nextToken());
H = Integer.parseInt(st.nextToken());
map = new int[H][W];
int sx = 0, sy = 0;
for (int i=0; i<H; i++) {
String str = br.readLine();
for (int j=0; j<W; j++) {
int tmp = str.charAt(j);
if (tmp == 'T') {
sx = i;
sy = j;
}
else if (tmp == 'R') map[i][j] = Rock;
else if (tmp == 'H') map[i][j] = Hole;
else if (tmp == 'E') map[i][j] = Escape;
else map[i][j] = tmp - '0';
}
}
bfs(sx, sy);
if (ans == Integer.MAX_VALUE) System.out.println(-1);
else System.out.println(ans);
}
public static void bfs(int x, int y) {
PriorityQueue<Pos> pq = new PriorityQueue<>();
boolean[][] visited = new boolean[H][W];
pq.add(new Pos(x, y, 0));
while (!pq.isEmpty()) {
Pos cur = pq.poll();
if (visited[cur.x][cur.y]) continue;
visited[cur.x][cur.y] = true;
for (int d=0; d<4; d++) {
int nx = cur.x;
int ny = cur.y;
int sec = cur.sec;
while (true) {
nx += dx[d];
ny += dy[d];
if (nx < 0 || ny < 0 || nx >= H || ny >= W) break;
if (map[nx][ny] == Hole) break;
if (map[nx][ny] == Rock) {
nx -= dx[d];
ny -= dy[d];
pq.add(new Pos(nx, ny, sec));
break;
}
if (map[nx][ny] == Escape) {
ans = Math.min(ans, sec);
break;
}
sec += map[nx][ny];
}
}
}
}
}

 

반응형