코딩문제풀이/Baekjoon
[Java] 백준 1525번 : 퍼즐
코딩하는 포메라니안
2023. 1. 24. 21:37
1. 문제
https://www.acmicpc.net/problem/1525
1525번: 퍼즐
세 줄에 걸쳐서 표에 채워져 있는 아홉 개의 수가 주어진다. 한 줄에 세 개의 수가 주어지며, 빈 칸은 0으로 나타낸다.
www.acmicpc.net
2. 풀이 과정
특정 상태까지의 최소 이동 시간을 구하기 때문에, BFS로 탐색하였다.
여기서 고민했던 부분은 방문 체크였다.
이미 이전에 고려했던 2차원 배열의 상태는 다시 볼 필요가 없기 때문에,
이 2차원 배열을 int형 숫자하나인 123456780 식으로 변환해서 방문체크를 하고 너비우선탐색을 진행했다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static int bfs(int zeroIdx, int start){
if(start == 123456780){
return 0;
}
int result = 0;
int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
Set<Integer> visited = new HashSet<>();
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{zeroIdx, start});
visited.add(start);
while(!q.isEmpty()){
result++;
for(int i = 0, size = q.size(); i < size; i++){
int[] now = q.poll();
int x = now[0] / 3;
int y = now[0] % 3;
for(int j=0; j<4; j++){
int nx = x + dx[j];
int ny = y + dy[j];
if(nx<0 || nx>=3 || ny<0 || ny>=3){ continue;}
int nextIdx = nx*3 + ny;
int next = swap(now[1], now[0], nextIdx);
if(next == 123456780){ return result;}
if(!visited.contains(next)){
visited.add(next);
q.add(new int[]{nextIdx, next});
}
}
}
}
return -1;
}
public static int swap(int num, int zeroIdx, int changeIdx){
int lenIdx = 8;
int su = (int)(num / Math.pow(10, lenIdx - changeIdx) % 10);
num -= su * Math.pow(10, lenIdx - changeIdx);
num += su * Math.pow(10, lenIdx - zeroIdx);
return num;
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int zeroIdx = 0, input = 0;
for(int i=0; i<3; i++){
st = new StringTokenizer(br.readLine());
for(int j=0; j<3; j++){
int num = Integer.parseInt(st.nextToken());
if(num == 0){
zeroIdx = i*3 + j;
}
input = (input * 10) + num;
}
}
System.out.println(bfs(zeroIdx, input));
}
}