【代码】八数码难题模板 [宽搜]
P1379 八数码难题 - 洛谷
/*
1 2 3
4 5 6
7 8 9
*/
#include<bits/stdc++.h>
using namespace std;typedef long long LL;
const LL inf = 1e9;
LL st, ed;
map<LL, bool> mp;struct State {LL s; // 状态 int p; // 0 的位置 int k; // 当前移动次数
};LL swap_state(LL sta, int x, int y) { // 交换状态 sta 里第 x 个和第 y 个的位置 if (x > y) {swap(x, y);}int t = 0, a, b;for (LL i = inf; i >= 10; i /= 10) {t ++;if (t == x) {a = (sta % i) / (i / 10);}if (t == y) {b = (sta % i) / (i / 10);}} LL new_s = sta;t = 0;for (LL i = inf; i >= 10; i /= 10) {t ++;if (t == x) {new_s -= a * (i / 10);new_s += b * (i / 10);}if (t == y) {new_s -= b * (i / 10);new_s += a * (i / 10);}} return new_s;
}int get_ans(State tmp) {queue<State> Q;Q.push(tmp);while (!Q.empty()) {State x = Q.front(); Q.pop();if (mp[x.s]) {continue;}mp[x.s] = 1;if (x.s == ed) {return x.k;}if (x.p - 3 > 0) { // 0 的位置不在最上面一行,可以和上面的数交换位置 State tmp = {swap_state(x.s, x.p, x.p - 3), x.p - 3, x.k + 1};Q.push(tmp);}if (x.p + 3 <= 9) { // 0 的位置不在最下面一行,可以和下面的数交换位置 State tmp = {swap_state(x.s, x.p, x.p + 3), x.p + 3, x.k + 1};Q.push(tmp);}if (x.p % 3 != 1) { // 0 的位置不在最左边一列,可以和左边的数交换位置 State tmp = {swap_state(x.s, x.p, x.p - 1), x.p - 1, x.k + 1};Q.push(tmp);}if (x.p % 3 != 0) { // 0 的位置不在最右边一列,可以和右边的数交换位置 State tmp = {swap_state(x.s, x.p, x.p + 1), x.p + 1, x.k + 1};Q.push(tmp);}}return 0;
}int main () {ios::sync_with_stdio(false);cin.tie(0);cin >> st;State tmp = {st, 0, 0};// 找初始状态 0 的位置 for (LL i = inf; i >= 10; i /= 10) {tmp.p ++; if ((st % i) / (i / 10) == 0) {break;}}ed = 123804765;cout << get_ans(tmp) << "\n";return 0;
}
