[BOJ] 1525. 퍼즐- (Java)
Problem
제출일 : 2020-03-22
문제 풀이 시간 : 1H 30M
난이도 : ★★★
3×3 표에 다음과 같이 수가 채워져 있다. 오른쪽 아래 가장 끝 칸은 비어 있는 칸이다.
1 | 2 | 3 |
---|---|---|
4 | 5 | 6 |
7 | 8 |
어떤 수와 인접해 있는 네 개의 칸 중에 하나가 비어 있으면, 수를 그 칸으로 이동시킬 수가 있다. 물론 표 바깥으로 나가는 경우는 불가능하다. 우리의 목표는 초기 상태가 주어졌을 때, 최소의 이동으로 위와 같은 정리된 상태를 만드는 것이다. 다음의 예를 보자.
1 | 3 | |
---|---|---|
4 | 2 | 5 |
7 | 8 | 6 |
1 | 2 | 3 |
---|---|---|
4 | 5 | |
7 | 8 | 6 |
1 | 2 | 3 |
---|---|---|
4 | 5 | |
7 | 8 | 6 |
1 | 2 | 3 |
---|---|---|
4 | 5 | 6 |
7 | 8 |
가장 윗 상태에서 세 번의 이동을 통해 정리된 상태를 만들 수 있다. 이와 같이 최소 이동 횟수를 구하는 프로그램을 작성하시오.
Input
세 줄에 걸쳐서 표에 채워져 있는 아홉 개의 수가 주어진다. 한 줄에 세 개의 수가 주어지며, 빈 칸은 0으로 나타낸다.
Output
첫째 줄에 최소의 이동 횟수를 출력한다. 이동이 불가능한 경우 -1을 출력한다.
Example
input
1 0 3
4 2 5
7 8 6
output
3
Solution & Inpression
맵의 상태를 정수형으로 변환 Set자료구조를 이용한 방문 확인
Code
언어 : JAVA
메모리 : 63944 kb
실행 시간 : 688 ms
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Gold3_1525_퍼즐 {
static int[] dr = { -1, 1, 0, 0 };
static int[] dc = { 0, 0, -1, 1 };
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int map = 0;
int[] start = new int[2];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int tmp = sc.nextInt();
map *= 10;
map += tmp;
if (tmp == 0) {
map += 9;
start[0] = i;
start[1] = j;
}
}
}
Queue<int[]> q = new LinkedList<>();
q.add(new int[] { map, start[0], start[1], 0 });
Set<Integer> set = new TreeSet<>();
set.add(map);
while (!q.isEmpty()) {
if (q.peek()[0] == 123456789) {
System.out.println(q.peek()[3]);
System.exit(0);
}
char[] now = ("" + q.peek()[0]).toCharArray();
int r = q.peek()[1];
int c = q.peek()[2];
int cnt = q.peek()[3];
q.poll();
for (int k = 0; k < dr.length; k++) {
int nr = r + dr[k];
int nc = c + dc[k];
if (isRange(nr, nc)) {
int next = getNext(now, r * 3 + c, nr * 3 + nc);
if (!set.contains(next)) {
set.add(next);
q.offer(new int[] { next, nr, nc, cnt + 1 });
}
}
}
}
System.out.println(-1);
}
private static int getNext(char[] now, int i, int j) {
char tmp = now[i];
now[i] = now[j];
now[j] = tmp;
int ret = 0;
for (char c : now) {
ret *= 10;
ret += c - '0';
}
tmp = now[i];
now[i] = now[j];
now[j] = tmp;
return ret;
}
private static boolean isRange(int nr, int nc) {
if (0 <= nr && nr < 3 && 0 <= nc && nc < 3)
return true;
return false;
}
}
'Problem > BOJ' 카테고리의 다른 글
[BOJ] 12851. 숨바꼭질2 - (Java) (0) | 2020.03.22 |
---|---|
[BOJ] 2251. 물통 - (Java) (0) | 2020.03.22 |
[BOJ] 1175. 배달 - (Java) (0) | 2020.03.22 |
[BOJ] 1039. 교환 - (Java) (0) | 2020.03.21 |
[BOJ] 1072. 게임 - (Java) (0) | 2020.03.18 |