八數碼 雜湊錶鏈表法
阿新 • • 發佈:2018-12-02
#include<bits/stdc++.h> using namespace std; typedef int State[9]; const int maxstate = 1e6; State st[maxstate], goal; int dist[maxstate]; const int dx[4] = { -1,1,0,0 };//用來控制x座標的移動 const int dy[4] = { 0,0,-1,1 };//用來控制y座標的移動 const int hashsize = 1e6 + 3;用來取模 int head[hashsize], nxt[maxstate];//head和nxt陣列是用來構建雜湊連結串列 int hashs(State& s)//構建雜湊表 { int v = 0; for (int i = 0; i < 9; i++) v = v * 10 + s[i]; return v % hashsize; } int try_to_insert(int s) { int h = hashs(st[s]); int u = head[h]; while (u) { if (memcmp(st[u], st[s], sizeof(st[s])) == 0) return 0; u = nxt[u]; } nxt[s] = head[h];//可以看出這裡使用的是連結串列法來解決衝突 head[h] = s; return 1; } int bfs() { int front = 1, rear = 2; while (front < rear) { State&s = st[front];//這裡的“&”不是取地址,在c++中表示引用,有點類似於指標的感覺,就是如果你對s進行修改,那麼相對應的st【】的那個也會修改; if (memcmp(goal, s, sizeof(s)) == 0) return front; int z; for (z = 0; z < 9; z++) if (!s[z]) break; int x = z / 3, y = z % 3; for (int d = 0; d < 4; d++) { int newx = x + dx[d], newy = y + dy[d]; int newz = newx * 3 + newy; if (newx < 0 || newx >= 3 || newy < 0 || newy >= 3) continue; State& t = st[rear]; memcpy(&t, &s, sizeof(s)); t[newz] = s[z]; t[z] = s[newz]; dist[rear] = dist[front] + 1; if (try_to_insert(rear)) rear++; } front++; } return 0; } int main() { for (int i = 0; i < 9; i++) scanf("%d", &st[1][i]);//輸入初始狀態的八數碼圖 for (int i = 0; i < 9; i++) scanf("%d", &goal[i]);//輸入你想要的終態八數碼圖 int ans = bfs();//進行bfs搜尋 if (ans > 0) printf("%d", dist[ans]); return 0; }
關於八數碼,詳見http://acm.hdu.edu.cn/showproblem.php?pid=1043
關於這道題,我也寫了部落格https://blog.csdn.net/qq_41670466/article/details/84316948裡面使用康託展開,大家可以自己百度一下。