You need to know the following points when learning the eight-digit * search problem:
Hash: Use Cantor to expand the hash
Cantor's expansion is mainly based on a sequence to find the sequence is the number of the first.
A * search: Here the heuristic function is calculated using the distance between two points in Manhattan.
Branch: In eight digital, arbitrary exchange of a blank line and a position of the number, the eight-digit inverse number is unchanged, so that the current state can be judged whether it can reach the end of the state.
The first time to do this problem with a hash of the map, the result of a decisive timeout, and then wrote the LRJ book on the hash method also timed out, finally can only use Cantor launched
For more information, please refer to: "Eight-digit eight-http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html"
/* Cantor expand A * algorithm eight digital inverse number properties */#include <cmath> #include <queue> #include <cstdio> #include <cstring> #i nclude<algorithm>using namespace Std;const int maxn = 370015;//322560struct state{int mat[3][3]; int h,g,cvalue; int posx,posy; friend bool operator < (state p,state Q) {if (p.h! = q.h) return p.h > Q.h; else return P.G > q.g; }}start;int vis[maxn],fa[maxn],cnt;//-------------------init----------------------------------void init () {memset (Vis,-1,sizeof (VIS)); memset (fa,-1,sizeof (FA)); CNT = 0;} BOOL isOK (state &state) {int temp[9]; for (int i = 0,k = 0; i < 3; i + +) for (int j = 0; j < 3; j++,k++) temp[k] = State.mat[i][j]; int ret = 0; for (int i = 0, i < 9; i++) for (int j = 0; J < i; J + +) {if (Temp[i] && temp[j] && te MP[J] > Temp[i]) ret + +; } return (Ret & 1)? 0:1;} //---------------------------------------------------------const int hash[] = {1,1,2,6,24,120,720,5040,40320};int Cantor (state &stemp) {int temp[9]; for (int i = 0,k = 0; i < 3; i++) for (int j = 0; J < 3; J + +, k++) temp[k] = Stemp.mat[i][j]; int ret = 0; for (int i = 0; i < 9; i++) {int val = 0; for (int j = 0; J < i; j + +) if (Temp[j] > Temp[i]) val + +; RET + = hash[i] * val; } return ret;} ----------------------------------------------------------int Get_h (state &temp) {int ret = 0; for (int i = 0, i < 3; i++) for (int j = 0; J < 3; J + +) {ret + = ABS (I-(temp.mat[i][j]- 1)/3) + ABS (J-(Temp.mat[i][j]-1)% 3); } return ret;} ----------------------------------------------------------//ulldrdrulldrruldlurrdconst char cdir[] = "DLRU"; const int Dir[4][2] = {{1,0},{0,-1},{0,1},{-1,0}}; D l r uvoid dfs_print (int u) {if (Vis[u] < 0) return; Dfs_print (fA[u]); printf ("%c", Cdir[vis[u]);} BOOL BFs () {priority_queue<state>q; Start.cvalue = Cantor (start); Start.h = Get_h (start); START.G = 0; Q.push (start); Vis[start.cvalue] =-2; State temp; while (!q.empty ()) {state now = Q.top (); Q.pop (); if (Now.cvalue = = 322560) {dfs_print (now.cvalue); Puts (""); return true; } for (int i = 0; i < 4; i++) {temp = now; int x = Now.posx + dir[i][0]; int y = now.posy + dir[i][1]; TEMP.POSX = x; Temp.posy = y; if (x >= 0 && x < 3 && y >= 0 && y < 3) {swap (temp.mat[x][y],temp.mat[no W.posx][now.posy]); int cvalue = Cantor (temp); if (vis[cvalue] = =-1 && isok (temp)) {Vis[cvalue] = i; Fa[cvalue] = Now.cvalue; Temp.h = Get_h (temp); TEMP.G = NoW.G + 1; Temp.cvalue = Cvalue; Q.push (temp); if (Temp.cvalue = = 322560) {dfs_print (cvalue); Puts (""); return true; } CNT + +; }}}} return false;} int main () {char _in[10][2]; while (scanf ("%s", _in[0])! = EOF) {init (); for (int i = 1; i < 9; i++) scanf ("%s", _in[i]); for (int k = 0,i = 0, i < 3; i++) for (int j = 0; j < 3; J++,k + +) {if (_in[k][0] = = ' x ') { _in[k][0] = ' 0 '; Start.posx = i; Start.posy = j; } Start.mat[i][j] = _in[k][0]-' 0 '; } if (!bfs ()) printf ("unsolvable\n"); } return 0;} /*12624120720504040320*/
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 10,438 Digital (* search)