반응형
728x90
반응형
문제
에너지를 효율적으로 사용하고자 화성 탐사 기계가 출발 지점에서 목표 지점까지 이동할때 항상 최적의 경로를 찾아야한다. N x N 크기의 2차원 배열에 각각의 칸을 지나기 위한 비용이 존재한다. 가장 왼쪽칸 [0][0] 에서 가장 오른쪽 아래칸 [N - 1][N - 1] 위치로 이동하는 최소비용을 출력하라. 화성탐사 기계는 특정한 위치에서 상하좌우 인접한 곳으로 1칸씩 이동할 수 있다.
풀이코드
package seohae.thiscodingtest.part03.Q39_MarsExploration;
import java.util.*;
/*
- 구현 후 로직 디버깅 (distance)
5 5 4
3 9 1
3 2 7 의 경우
(1)
[1000000000, 1000000000, 1000000000],
[1000000000, 1000000000, 1000000000],
[1000000000, 1000000000, 1000000000]
(2)
[5, 1000000000, 1000000000],
[8, 1000000000, 1000000000],
[1000000000, 1000000000, 1000000000]
(3) 10은 5 + 5 (상하좌우로만 이동이 가능할때, 좌에서 오는 경우가 최단)
[5, 10, 1000000000],
[8, 1000000000, 1000000000],
[1000000000, 1000000000, 1000000000]
(4) 11은 8 + 3 (상 (8) + 3)
[5, 10, 1000000000],
[8, 1000000000, 1000000000],
[11, 1000000000, 1000000000]
(5) 17은 8 + 9
[5, 10, 1000000000],
[8, 17, 1000000000],
[11, 1000000000, 1000000000]
(6)
[5, 10, 14],
[8, 17, 1000000000],
[11, 1000000000, 1000000000]
(7)
[5, 10, 14],
[8, 17, 1000000000],
[11, 13, 1000000000]
(8)
[5, 10, 14],
[8, 17, 1000000000],
[11, 13, 20]
(9) 결국 distance[N-1][N-1] 20이 결과다.
[5, 10, 14],
[8, 17, 15],
[11, 13, 20]
*/
public class Main {
/* 무한을 의미하는 값으로 10억을 설정 */
static final int INF = (int) 1e9;
static int num;
static int N;
static int[][] graph;
static int[][] distance;
static List<Integer> resultList = new ArrayList<>();
public static void main(String[] args) {
input();
resultList.stream().forEach(System.out::println);
}
/*
3
3
5 5 4
3 9 1
3 2 7
5
3 7 2 0 1
2 8 0 9 1
1 2 1 8 1
9 8 9 2 0
3 6 5 1 5
7
9 0 5 1 1 5 3
4 1 2 1 6 5 3
0 7 6 1 6 8 5
1 1 7 8 3 2 3
9 4 0 7 6 4 1
5 8 3 2 4 8 3
7 4 8 4 8 3 4
*/
private static void input() {
Scanner sc = new Scanner(System.in);
num = sc.nextInt();
for (int n = 0; n < num; n++) {
N = sc.nextInt();
graph = new int[N][N];
distance = new int[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
graph[i][j] = sc.nextInt();
distance[i][j] = INF;
}
}
/* 알고리즘 수행 */
dijkstra(0, 0);
resultList.add(distance[N - 1][N - 1]);
}
}
/**
* 기존에 공부했던 다익스트라를 2차배열로 구성하여 최단거리 update
* @param x
* @param y
*/
private static void dijkstra(int x, int y) {
/* 우선순위 큐 선언 */
PriorityQueue<MarsNode> pq = new PriorityQueue<>();
/* 시작 노드로 가기 위한 최단 경로는 현재의 값으로 설정하고 큐에 삽입 */
distance[x][y] = graph[x][y];
pq.offer(new MarsNode(x, y, distance[x][y]));
/* 큐가 비어있지않을 때까지 반복 */
while (!pq.isEmpty()) {
/* 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 */
MarsNode node = pq.poll();
/* 현재의 정보 */
int nowDistance = node.getDistance();
int nowX = node.getX();
int nowY = node.getY();
/* 이동 : 상, 하, 좌, 우 */
int[] dx = new int[]{-1, 1, 0, 0};
int[] dy = new int[]{0, 0, -1, 1};
for (int i = 0; i < 4; i++) {
/* 이동 정보 */
int nx = nowX + dx[i];
int ny = nowY + dy[i];
/* 이동 가능한 지점일 경우 */
if (nx >= 0 && ny >= 0 && nx < N && ny < N) {
/* nowDistance : 현재 지점의 거리
graph[nx][ny] : 이동될 지점의 값
distance[nx][ny] : 이동될 지점의 현재까지의 최단거리
*/
if (nowDistance + graph[nx][ny] < distance[nx][ny]) {
/* 최단거리 갱신 */
distance[nx][ny] = nowDistance + graph[nx][ny];
/* 큐 삽입 */
pq.add(new MarsNode(nx, ny, distance[nx][ny]));
}
}
// 결과 지점이 셋팅되었다면 break;
if (distance[N - 1][N - 1] != INF) {
break;
}
}
}
}
}
class MarsNode implements Comparable<MarsNode> {
private int x;
private int y;
private int distance;
public MarsNode(int x, int y, int distance) {
this.x = x;
this.y = y;
this.distance = distance;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
// 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정
@Override
public int compareTo(MarsNode other) {
if (this.distance < other.distance) {
return -1;
}
return 1;
}
}
반응형
'Algorithm > Problem Solving' 카테고리의 다른 글
[Baekjoon 1238번] 파티 문제 (with 자바) (0) | 2022.03.15 |
---|---|
[Baekjoon 1439번] 뒤집기 문제 (with 자바) (0) | 2022.02.05 |
[프로그래머스] Level2 60057번: 문자열 압축 (JAVA) (0) | 2022.01.17 |
[이것이 코딩테스트다] 실전문제31. 금광 (JAVA) (0) | 2022.01.07 |
[프로그래머스] Level1 42889번: 실패율 (JAVA) (0) | 2022.01.02 |