路径寻找问题……!
一开始哈希表那部分死活看不懂……
就是你找到head[]数组标记的每个哈希数最开始的坐标。
然后 next[]数组标记的是相同的哈希数的一条链……
主要代码……
bool try_to_insert(int s){ int h = hash(st[s]); /*相对应的哈希数*/ int u = head[h]; ///*head数组一开始初始化为0,为链首*/ while(u){ /*一直找到为0的情况……!*/ if(memcmp(&st[u],&st[s],sizeof(st[s])) == 0) ///*如果找到相同的返回0*/ return 0; u = next[u];///*链的下一个……*/ } next[s] = head[h]; head[h] = s; ///*形成链,串起来!!!*/ return 1; }
题意就是3*3的方格有一个数目为0表示空,然后和相邻的之间可以滑动,问一个给定的布局变换到目标布局的最小步数。
嗨嗨嗨……!!!自己还是弱爆了……!
主要书bfs搜索……
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <cstdlib> #include <stack> #include <cctype> #include <string> #include <malloc.h> #include <queue> #include <map> using namespace std; const int INF = 0xffffff; const double esp = 10e-8; const double Pi = 4 * atan(1.0); const int Maxn = 1000000; const int mod = 10000007; const int dr[] = {1,0,-1,0,-1,1,-1,1}; const int dc[] = {0,1,0,-1,1,-1,-1,1}; const int hashsize = 1000003; int head[hashsize],next[Maxn]; typedef int State[9]; State st[Maxn],goal; //状态数组 int dist[Maxn]; void init_lookup_table(){ memset(head,0,sizeof(head)); memset(dist,0,sizeof(dist)); memset(next,0,sizeof(next)); } int hash(State & s){ int v = 0; for(int i = 0;i < 9;i++){ v += v * 10 + s[i]; } return v % hashsize; } bool try_to_insert(int s){ int h = hash(st[s]); int u = head[h]; while(u){ if(memcmp(&st[s],&st[u],sizeof(st[s])) == 0){ return 0; } u = next[u]; } next[s] = head[h]; head[h] = s; return 1; } int bfs(){ init_lookup_table(); int front = 1; int rear = 2; while(front < rear){ State &s = st[front]; if(memcmp(s,goal,sizeof(s)) == 0) return front; int z; for(z = 0;z < 9;z++){ if(!s[z]) break; } int x = z/3; int y = z%3; for(int i = 0;i < 4;i++){ int xx = x + dr[i]; int yy = y + dc[i]; int zz = xx * 3 + yy; if(xx >= 0 && xx < 3 && yy >= 0 && yy < 3){ State &t = st[rear]; memcpy(&t,&s,sizeof(s)); t[zz] = s[z]; t[z] = s[zz]; dist[rear] = dist[front]+1; if(try_to_insert(rear) == 1){ rear++; /* for(int j = 0;j < 9;j++){ if(j % 3 == 0) cout << endl; cout << t[j]; } cout << endl; if(rear == 70) return -1;*/ } } } front++; } return 0; } int main() { #ifndef ONLINE_JUDGE freopen("inpt.txt","r",stdin); #endif 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(); if(ans > 0) printf("%d\n",dist[ans]); else printf("-1\n"); return 0; }