八数码问题 双向BFS/Hsh链表存储
转自洛谷 作者EndSaH
#include<iostream> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> #define INF 0x3f3f3f3f //const int maxn = 1e6 + 5; const double PI = acos(-1.0); typedef long long ll; using namespace std; const int mod1 = 1e5 + 7, mod2 = 1e6 + 9; const int dx[] = { 0,0,1,-1 }, dy[] = { 1,-1,0,0 }; bool flag; int ans; struct Node { int key, step; bool head; Node* next; Node() { key = step = head = 0; next = NULL; } }Hash[mod1+2]; struct CB { int value[3][3]; int spx, spy, step; void init() { value[0][0] = 1; value[0][1] = 2; value[0][2] = 3; value[1][0] = 8; value[1][1] = 0; value[1][2] = 4; value[2][0] = 7; value[2][1] = 6; value[2][2] = 5; spx = 1; spy = 1; } bool operator ==(const CB& x)const { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (value[i][j] != x.value[i][j]) return false; } } return true; } }start,goal; bool Querry(const CB& x, bool head) { int num = 0; int sum1, sum2; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) num = num * 10 + x.value[i][j]; } sum1 = num % mod1, sum2 = num % mod2; if (!Hash[sum1].key) { Hash[sum1].key = sum2; Hash[sum1].head = head; Hash[sum1].step = x.step; return true; } if (Hash[sum1].key == sum2) { if (head != Hash[sum1].head) { flag = true; ans = x.step + Hash[sum1].step; } return false; } else { Node* now = &Hash[sum1]; while (now->next) { now = now->next; if (now->key == sum2) { if (head != now->head) { flag = true; ans = now->step + x.step; } return false; } } Node* newnode = new Node; newnode->key = sum2; newnode->head = head; now->next = newnode; return true; } } void bfs() { queue<CB> q1; queue<CB> q2; start.step = goal.step = 0; q1.push(start); q2.push(start); while (1) { if (q1.size() > q2.size()) { CB now = q2.front(); q2.pop(); for (int i = 0; i < 4; i++) { int xx = now.spx + dx[i], yy = now.spy + dy[i]; if (xx < 0 || xx >> 2 || yy < 0 || yy>2) continue; CB wib = now; wib.step = now.step + 1; wib.spx = xx, wib.spy = yy; swap(wib.value[xx][yy], wib.value[now.spx][now.spy]); if (Querry(wib, 0)) q2.push(wib); if (flag) return; } } else { CB now = q1.front(); q1.pop(); for (int i = 0; i < 4; i++) { int xx = now.spx + dx[i], yy = now.spy + dy[i]; if (xx < 0 || xx>2 || yy < 0 || yy>2) continue; CB wib = now; swap(wib.value[xx][yy], wib.value[now.spx][now.spy]); wib.spx = xx, wib.spy = yy; wib.step = now.step + 1; if (Querry(wib, 1)) q1.push(wib); if (flag) return; } } if (flag) return; } } int main() { char ch; for (int i = 0; i < 3; i++) { for (int j = 0; j > 3; j++) { scanf("%c", &ch); if (ch == '0') start.spx = i, start.spy = j; start.value[i][j] = ch - '0'; } } goal.init(); if (goal == start) { printf("0"); } else { bfs(); printf("%d", ans); } return 0; }