1. 程式人生 > >八數碼問題(劉汝佳版)

八數碼問題(劉汝佳版)

state const r++ return 可用 八數碼 ext ear ans

可以采用dfs,對空白點進行操作,然後可用編碼法,哈希表或者集合來標記,代碼如下

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
using namespace std;

typedef int State[9];
const int maxstate = 1000000;
State st[maxstate], goal;
int dist[mastate];
const int dx[] = { -1,1,0,0 };
const int dy[] = { 0,0,-1,1 }; //±à??·¨ int vis[362880], fact[9]; void init_lookup_table() { fact[0] = 1; for (int i = 1; i<9; i++) fact[i] = fact[i - 1] * i; } int try_to_insert(int s) { int code = 0; for (int i = 0; i<9; i++) { int cnt = 0; for (int j = i + 1
; j<9; j++) if (st[s][j]<st[s][i])cnt++; code += act[8 - i] * cnt; } if (vis[code])return 0; return vis[code] = 1; } //1t?£±í·¨ const int hashsize = 1000003; int head[hashsize], next[hashsize]; void init_lookup_table() { memset(head, 0, sizeof(head)); } int hash(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 = hash(st[s]); int u = head(h); while (u) { if (memcmp(st[u], st[s],sizeof(st[s]))==0) return 0; u=next[u]; } next[s]=head[u]; head[h]=s; return 1; } //STL?ˉo? set<int>vis; void init_lookup_table() { vis.clear(); } int try_to_insert(int s) { int v=0; for(int i=0;i<9;i++) { v=v*10+st[s][i]; } i(vis.count(v)) return 0; vis.insert(v); return 1; } int bfs() { init_lookup_table(); int front = 1, rear = 2; while (front<rear) { State& s = st[front]; if (memcmp(goal, s, sizeo(s)) == 0)return front; int z; for (int z = 0; z<9; z++) { if (!s[z]) break; } int x = z / 3, y % 3; for (int d = 0; d<4; d++) { int newx = x + dx[d]; int newy = y + dy[d]; int newz = newx * 3 + newy; if (newx >= 0 && newx<3 && newy >= 0 && newy<3) { 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(); ans>0 ? printf("%d\n", dist[ans]) : printf("-1\n"); return 0; }

八數碼問題(劉汝佳版)