티스토리 뷰
https://www.acmicpc.net/problem/1525
코드
2차원으로 배열을 다루지 않고 1차원으로 다루었다.
코드를 작성하면서 배웠던 것은 String이 아닌 StringBuffer 또는 StringBuilder를 사용하면 문자열의 특정 인덱스 값을 수정할 수 있다. 덕분에 String의 substring을 사용할 필요가 없어졌다.
import java.io.*;
import java.util.*;
public class Main {
static Map<String, Integer> map = new HashMap<>();
static Queue<String> que = new LinkedList<>();
static int[] dx = {1, -1, 0, 0};
static int[] dy = {0, 0, 1, -1};
static final String BREAK = "123456780";
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 3; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < 3; j++) {
sb.append(st.nextToken());
}
}
que.offer(sb.toString());
map.put(sb.toString(), 0);
System.out.println(bfs());
}
static int bfs() {
while (!que.isEmpty()) {
String str = que.poll();
int idx = str.indexOf("0");
int xIdx = idx / 3;
int yIdx = idx % 3;
for (int d = 0; d < 4; d++) {
int cx = xIdx + dx[d];
int cy = yIdx + dy[d];
if (isNotOutOfRange(cx, cy)) {
StringBuilder sb = new StringBuilder(str);
char tmp = str.charAt(cx * 3 + cy);
sb.setCharAt(cx * 3 + cy, '0');
sb.setCharAt(idx, tmp);
if (!map.containsKey(sb.toString())) {
map.put(sb.toString(), map.get(str) + 1);
que.offer(sb.toString());
}
}
}
}
if (map.containsKey(BREAK)) {
return map.get(BREAK);
} else {
return -1;
}
}
static boolean isNotOutOfRange(int x, int y) {
return x >= 0 && x < 3 && y >= 0 && y < 3;
}
}