# 【TIOJ】1198. 8-Puzzle
## [題目連結](https://tioj.ck.tp.edu.tw/problems/1198)
## **時間複雜度**
* $O(1 \approx 9!)$
## **解題想法**
這題的分類歸類到枚舉中的隱式圖中,他的解法是將每個可能的狀態當成一個節點,然後再用 BFS 去搜步數最少的解,最後輸出就可以了
實作上需要注意的地方有
1. `visited` 改成用 `map<vector<int>, int>` 去存
2. 最後答案一定會在 `used[{target_vector}]` 中
## **完整程式**
```cpp=
/* Question : TIOJ 1198. 8-puzzle */
#include<bits/stdc++.h>
using namespace std;
#define opt ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define pirq(type) priority_queue<type, vector<type>, greater<type>>
#define mem(x, value) memset(x, value, sizeof(x));
#define pii pair<int, int>
#define pdd pair<double, double>
#define pb push_back
#define f first
#define s second
#define int long long
#define n 9
const auto dir = vector< pair<int, int> > { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
const int MAXN = 9 + 50;
const int Mod = 1e9 + 7;
map<vector<int>, int> used;
queue<vector<int>> q;
vector<int> st, ed;
signed main(){
opt;
int x;
st.resize(10);
ed.resize(10);
for ( int i = 0 ; i < n ; i++ ) cin >> st[i];
for ( int i = 0 ; i < n ; i++ ) cin >> ed[i];
q.push(st);
while ( !q.empty() ){
vector<int> cnt = q.front();
q.pop();
int emp = 0, cntd = used[cnt];
while ( cnt[emp] ) emp++; // Find the Empty Space
if ( emp >= 3 ) { // If Available to Go Up
swap( cnt[emp], cnt[emp-3] );
if ( !used[cnt] ){
used[cnt] = cntd+1;
q.push(cnt);
}
if ( cnt == ed ) break;
swap( cnt[emp], cnt[emp-3] );
}
if ( emp <= 5 ) { // If Available to Go Down
swap(cnt[emp], cnt[emp+3]);
if ( !used[cnt] ){
used[cnt] = cntd+1;
q.push(cnt);
}
if ( cnt == ed ) break;
swap(cnt[emp], cnt[emp+3]);
}
if ( emp % 3 != 0 ) { // If Available to Go Right
swap(cnt[emp], cnt[emp-1]);
if ( !used[cnt] ){
used[cnt] = cntd+1;
q.push(cnt);
}
if ( cnt == ed ) break;
swap(cnt[emp], cnt[emp-1]);
}
if ( emp % 3 != 2 ) { // If Available to Go Left
swap(cnt[emp], cnt[emp+1]);
if ( !used[cnt] ){
used[cnt] = cntd+1;
q.push(cnt);
}
if ( cnt == ed ) break;
swap(cnt[emp], cnt[emp+1]);
}
}
cout << used[ed] << "\n";
return 0;
}
```