题目
题解
BFS(+STL)
最少次数,每次跳跃对次数的贡献都是1,完全可以抽象理解为最短路,所以采用BFS可以直接算出最短长度。
状态转移存在四种,以题中给的状态为例,可以选择2跳到空处、1跳到空处、7跳到空处或8跳到空处。标记一下遇到过的状态,不要再加入队列中了。
代码
#include<bits/stdc++.h>
#define PIV pair <int, vector <int> >
using namespace std;
int ans = 0;
vector <int> target = {0, 8, 7, 6, 5, 4, 3, 2, 1}; // 目标状态
map <vector <int>, int> st; // 标记
vector <int> exchage (vector <int> v, int x, int y) {
swap (v[x], v[y]);
return v;
}
void bfs () {
queue <PIV> q; // I表示0的位置,V表示状态
vector <int> s;
s = {0, 1, 2, 3, 4, 5, 6, 7, 8};
q.push ({0, s});
st[s] = 1;
while (q.size()) {
int k = q.size ();
ans ++;
for (int i = 0;i < k;i ++) {
PIV t = q.front();
q.pop ();
int pos_0 = t.first, ex_pos; // pos_0 : 0的位置,ex_pos : 要跳跃的蚱蜢的位置
vector <int> state = t.second;
vector <int> new_state; // 跳后状态
ex_pos = (pos_0 + 1) % 9; // 有四种跳跃方式,从左上跳到空处两种,右侧两种,总共四种
new_state = exchage (state, pos_0, ex_pos); // 跳跃后的状态
if (new_state == target) return ; // 目标
if (st.count(new_state) == 0) { // 没遍历过该状态
q.push ({ex_pos, new_state}); // 扩展
st[new_state] = 1; // 标记
}
ex_pos = (pos_0 + 2) % 9;
new_state = exchage (state, pos_0, ex_pos);
if (new_state == target) return ;
if (st.count(new_state) == 0) {
q.push ({ex_pos, new_state});
st[new_state] = 1;
}
ex_pos = (pos_0 - 1 + 9) % 9;
new_state = exchage (state, pos_0, ex_pos);
if (new_state == target) return ;
if (st.count(new_state) == 0) {
q.push ({ex_pos, new_state});
st[new_state] = 1;
}
ex_pos = (pos_0 - 2 + 9) % 9;
new_state = exchage (state, pos_0, ex_pos);
if (new_state == target) return ;
if (st.count(new_state) == 0) {
q.push ({ex_pos, new_state});
st[new_state] = 1;
}
}
}
}
int main()
{
bfs ();
cout << ans << endl;
return 0;
}