본문 바로가기
ps

[백준]1525 - 퍼즐

by kariskan 2022. 7. 13.

https://www.acmicpc.net/problem/1525

 

1525번: 퍼즐

세 줄에 걸쳐서 표에 채워져 있는 아홉 개의 수가 주어진다. 한 줄에 세 개의 수가 주어지며, 빈 칸은 0으로 나타낸다.

www.acmicpc.net

 

흥미로운 문제였다.

 

2차원 배열 형태의 격자를 1차원 형태의 문자열처럼 만들고, map 자료구조를 이용해서 방문 체크를 할 수 있다.

원래는 빈 칸 주위의 숫자들을 빈칸으로 이동하면서 퍼즐을 맞추지만,

조금 더 편리하게 구현하기 위해 빈칸이 이동하는 것으로 생각해서 dx, dy 기법을 편리하게 이용할 수 있었다.

 

#include <iostream>
#include <map>
#include <queue>
using namespace std;
map<string, int> m;
int main() {
	string s = "";
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			char c; cin >> c;
			s += c;
		}
	}
	queue<string> q;
	q.push(s);
	m[s] = 1;
	int x[4] = { 0,0,1,-1 };
	int y[4] = { 1,-1,0,0 };
	while (!q.empty()) {
		string s = q.front();
		q.pop();
		if (s == "123456780") {
			cout << m[s] - 1;
			return 0;
		}
		int idx = s.find('0');
		int i = idx / 3;
		int j = idx % 3;
		for (int k = 0; k < 4; k++) {
			int nx = i + x[k];
			int ny = j + y[k];
			if (nx >= 0 && nx < 3 && ny >= 0 && ny < 3) {
				string t = s;
				char temp;
				temp = t[idx];
				t[idx] = t[nx * 3 + ny];
				t[nx * 3 + ny] = temp;
				if (m.find(t) == m.end()) {
					q.push(t);
					m[t] = m[s] + 1;
				}
			}
		}
	}
	cout << -1;
}

'ps' 카테고리의 다른 글

[백준] 1854 - K번째 최단경로 찾기  (0) 2022.07.19
[백준] 13904 - 과제  (0) 2022.07.19
[백준] 11003 - 최솟값 찾기  (0) 2022.07.14
[백준] 4196 - 도미노  (0) 2022.07.14
[백준]1766 - 문제집  (0) 2022.07.13

댓글