POJ 1077 Eight(BFS八数码问题)

#include #include using namespace std; typedef int State[9]; const int MAXS = 1000003; State st[MAXS],goal = {1,2,3,4,5,6,7,8,0}; int dir[4][2] = {-1,0,1,0,0,-1,0,1}; int head[MAXS],next[MAXS],fa[MAXS];//父亲指针用来记录状态之间的关联,方便打印解 vector ans;//保存方案 void printAns(int s) { ans.clear(); int z1,z2; while(fa[s] != -1) { for(int i = 0;i < 9;++i) { if(!st[s][i]) z1 = i; if(!st[fa[s]][i]) z2 = i; } if(z1 - z2 == 1) ans.push_back('r'); if(z1 - z2 == -1) ans.push_back('l'); if(z1 - z2 == 3) ans.push_back('d'); if(z1 - z2 == -3) ans.push_back('u'); s = fa[s]; } } void init() { memset(head,-1,sizeof(head)); memset(fa,-1,sizeof(fa)); } int hash(State &s)//哈希函数 { int h = 0; for(int i = 0;i < 9;++i) h = h*10 + s[i]; return h % MAXS; } int insert(int s)//插入哈希表 { int h = hash(st[s]); int u = head[h]; while(u != -1) { if(memcmp(st[u],st[s],sizeof(st[s])) == 0) return 0; u = next[u]; } next[s] = head[h]; head[h] = s; return 1; } int bfs() { init();//初始化hash表和fa int front = 1,rear = 2; while(front < rear) { State& s = st[front]; if(memcmp(goal,s,sizeof(s)) == 0) { printAns(front); return 1; } 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 X = x + dir[d][0]; int Y = y + dir[d][1]; int Z = X*3 + Y; if(X >= 0 && X < 3 && Y >= 0 && Y < 3) { State& t = st[rear]; memcpy(&t,&s,sizeof(s)); swap(t[Z],t[z]);//新状态空格与目标交换 fa[rear] = front; if(insert(rear)) rear++;//如果插入成功,尾指针++ } } front++;//拓展完所有状态,前指针++ } return 0; } int main() { char a; //freopen("in.txt","r",stdin); while(1) { for(int i = 0;i < 9;++i) if(scanf("/n%c/n",&a) == EOF) return 0; else { if(a != 'x') st[1][i] = a - '0'; else st[1][i] = 0; } if(!bfs()) printf("unsolvable/n"); else { for(int i = ans.size()-1;i >= 0;i--)//逆序打印解 printf("%c",ans[i]); printf("/n"); } } return 0; } 

你可能感兴趣的:(搜索)