-
BOJ 1525 : 퍼즐백준 문제풀이/GRAPH 2020. 1. 24. 01:16
문제
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 가장 윗 상태에서 세 번의 이동을 통해 정리된 상태를 만들 수 있다. 이와 같이 최소 이동 횟수를 구하는 프로그램을 작성하시오.
입력
세 줄에 걸쳐서 표에 채워져 있는 아홉 개의 수가 주어진다. 한 줄에 세 개의 수가 주어지며, 빈 칸은 0으로 나타낸다.
출력
첫째 줄에 최소의 이동 횟수를 출력한다. 이동이 불가능한 경우 -1을 출력한다.
코드 (풀이 생략합니다. 댓글에 질문 해주세요.)
#include <iostream> #include <algorithm> #include <map> #include <queue> #include <string> using namespace std; int dx[] = { 1, -1, 0, 0 }; int dy[] = { 0, 0, 1, -1 }; int main() { /////////////입력////////////// int n; int start = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { cin >> n; if (n == 0) n = 9; // 0은 몫,나머지를 못구함 start = start * 10 + n; } } ////////////map 구현///////////// map<int, int> qube; queue<int> q; qube.insert(make_pair(start, 0)); q.push(start); ////////////bgs//////////////// while (!q.empty()) { int now_num = q.front(); string now = to_string(now_num); q.pop(); int z = now.find('9'); int x = z / 3; // 큐브에서 0의 x좌표 int y = z % 3; // 큐브에서 0의 y좌표 for (int k = 0; k < 4; k++) { int nx = x + dx[k]; int ny = y + dy[k]; if (nx >= 0 && nx < 3 && ny >= 0 && ny < 3) { string next = now; swap(next[x * 3 + y], next[nx * 3 + ny]); int num = stoi(next); //string to int if (qube.count(num) == 0) { qube[num] = qube[now_num] + 1; //큐브를 한번 움직임 q.push(num); } } } } if (qube.count(123456789) == 0) cout << -1 << '\n'; else cout << qube[123456789] << '\n'; return 0; }
'백준 문제풀이 > GRAPH' 카테고리의 다른 글
BOJ 12906 : 새로운 하노이 탑 (0) 2020.03.06 BOJ 5213 : 과외맨 (0) 2020.02.19 BOJ 13913 : 숨박꼭질 4 (0) 2020.01.02 [BFS] BOJ 10026 : 적록색약 (0) 2019.10.01 [BFS] BOJ 2178 : 미로 탐색 (0) 2019.08.16