题解 luoguP1379 八数码难题

看到很多神仙都是一顿A* / 双向广搜 等操作。
其实状态数也没那么多
直接hash存储已经搜过的值,然后暴力地广搜就能过
用string来表示状态,map存一下就好了
#include <iostream>
#include <map>
#include <queue>
#define pis pair<int,string>
using namespace std;
const string end = "123804765";
inline int findZero(string s) { for(int i = 0; i < 9; ++i) if(s[i] == '0') return i; }
map<string, bool> hash;
queue<pis> q;
int bfs(string start) {
hash[start] = true;
q.push(make_pair(0, start));
while(!q.empty()) {
int d = q.front().first;
string cur = q.front().second;
q.pop();
if(cur == end) {
return d;
}
int x = findZero(cur);
string tmp;
if(x / 3 != 0) {
tmp = cur;
swap(tmp[x], tmp[x-3]);
if(!hash[tmp]) {
hash[tmp] = true;
q.push(make_pair(d + 1, tmp));
}
}
if(x % 3 != 0) {
tmp = cur;
swap(tmp[x], tmp[x - 1]);
if(!hash[tmp]) {
hash[tmp] = true;
q.push(make_pair(d + 1, tmp));
}
}
if(x % 3 != 2) {
tmp = cur;
swap(tmp[x], tmp[x + 1]);
if(!hash[tmp]) {
hash[tmp] = true;
q.push(make_pair(d + 1, tmp));
}
}
if(x / 3 != 2) {
tmp = cur;
swap(tmp[x], tmp[x + 3]);
if(!hash[tmp]) {
hash[tmp] = true;
q.push(make_pair(d + 1, tmp));
}
}
}
return -1;
}
int main() {
ios::sync_with_stdio(false);
string start;
cin >> start;
cout << bfs(start) << endl;
return 0;
}