八数码问题(hash+bfs)
2017-09-15 20:33
423 查看
小白P131
编号为1~8的8个正方形滑块被摆成3行3列(有一个格子留空)。每次可以把与空格相邻的滑块(有公共边才算相邻)移到空格中,而它原来的位置就成为了新的空格。给定初始局面和目标局面(用0表示空格),你的任务是计算出最少的移动步数。如果无解,输出-1。
![](https://img-blog.csdn.net/20140416145844718?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQval9zdXJl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
编号为1~8的8个正方形滑块被摆成3行3列(有一个格子留空)。每次可以把与空格相邻的滑块(有公共边才算相邻)移到空格中,而它原来的位置就成为了新的空格。给定初始局面和目标局面(用0表示空格),你的任务是计算出最少的移动步数。如果无解,输出-1。
#include<stdio.h> #include<string.h> const int N=1000000,HN=1000003; int nx[4][2]={-1,0,1,0,0,-1,0,1};//上下左右 int start [9],goal[9];//起始数组,目标数组 int first[HN],next ;//链表 int step ; int hash(int *start)//通过hash函数将每种状态转换成相同长度的整数 { int ha=0; for(int i=0;i<9;i++) ha=ha*10+start[i];//这是一个hash映射函数,通过他可以实现转换 return ha%HN; } bool try_insert(int tail)//相当于判断if(book[tx][ty]==0) { int ha=hash(start[tail]); int u=first[ha]; while(u) { if(!memcmp(start[u],start[tail],sizeof(start[0]))) return 0;//如果已经走过则返回0 u=next[u];//顺着链表继续找 } next[tail]=first[ha]; first[ha]=tail;//将这个点插入到链表中 return 1;//没有走过,扩展成功,返回1 } int bfs() { memset(first,0,sizeof(first)); int head=1,tail=2; while(head<tail) { if(memcmp(goal,start[head],sizeof(start[0]))==0) return head;//找到目标状态 int z;//注意将数据带出 for(z=0;z<9;z++) if(start[head][z]==0) break;//找到"0" int x=z/3,y=z%3;//转化为坐标形式,x表示行y表示列 for(int i= d6f6 0;i<4;i++) { int tx=x+nx[i][0]; int ty=y+nx[i][1]; int tz=3*tx+ty;//行x列y移动后再转化为下标形式 if(tx>=0&&tx<3&&ty>=0&&ty<3)//总共3行3列 { memcpy(&start[tail],&start[head],sizeof(start[0]));//将head中的点给tail start[tail][tz]=start[head][z]; start[tail][z]=start[head][tz];//将0所在的格与旁边的格中的数值交换 step[tail]=step[head]+1;//步数+1 if(try_insert(tail)) tail++;//相当于book,如果这步扩展成功则tail++ } } head++; } return 0; } int main() { for(int i=0;i<9;i++) scanf("%d",&start[1][i]); for(int i=0;i<9;i++) scanf("%d",&goal[i]); int s=bfs(); if(s>0) printf("%d\n",step[s]); else printf("-1\n"); return 0; }
#include<stdio.h> #include<string.h> #include<algorithm> #define M 500000 #define Mod 1000003 using namespace std; int s[9],goal[9],head[Mod],Next[Mod],end,director[M],tt,f; int nx[4][2]={0,-1,1,0,0,1,-1,0}; struct node { int str[9]; int step,first,dir; }Q[M]; int Hash(int ss[]) { int sum=0; for(int i=0;i<9;i++) sum=sum*10+ss[i]; return sum%Mod; } int Try_to_insert(int ss) { int h=Hash(Q[ss].str); int u=head[h]; while(u) { if(memcmp(Q[ss].str,Q[u].str,sizeof(goal))==0) return 0; u = Next[u]; } Next[ss]=head[h]; head[h]=ss; return 1; } void find(int x) { if(Q[x].dir==-1) return ; else { find(Q[x].first); director[tt++]=Q[x].dir; } } void bfs() { memcpy(Q[1].str,s,sizeof(s)); int head=1,tail=2; Q[head].step=0; Q[head].first=0; Q[head].dir=-1; Try_to_insert(1); while(head<tail) { int z; for(z=0;z<9;z++) if(!Q[head].str[z]) break; int y=z/3,x=z%3; for(int i=0;i<4;i++) { int tx=x+nx[i][0]; int ty=y+nx[i][1]; if(tx>=0&&tx<3&&ty>=0&&ty<3) { int tz=3*ty+tx; memcpy(Q[tail].str,Q[head].str,sizeof(goal)); swap(Q[tail].str[z],Q[tail].str[tz]); if(Try_to_insert(tail)) { Q[tail].step=Q[head].step+1; Q[tail].first = head; Q[tail].dir = i; if(memcmp(Q[tail].str,goal,sizeof(goal))==0) { f=1; end=tail; return ; } tail++; } } } head++; } } int main() { int i,j,k,t,n; char ss[1000]; while(gets(ss)!=NULL) { int l=strlen(ss); k=0; for(i=0;i<l;i++) { if(ss[i]>='0'&&ss[i]<='9') s[k++]=ss[i]-'0'; if(ss[i]=='x') s[k++]=0; } for(i=1;i<=9;i++) { if(i==9) goal[i-1]=0; else goal[i-1]=i; } if(memcmp(s,goal,sizeof(s))==0) { printf("\n"); continue; } memset(head,0,sizeof(head)); end=1; f=0; bfs(); tt=0; if(f) { find(end); for(i=0;i<tt;i++) { if(director[i]==0) printf("u"); else if(director[i]==1) printf("r"); else if(director[i]==2) printf("d"); else if(director[i]==3) printf("l"); } printf("\n"); } else printf("unsolvable\n"); } return 0; }
相关文章推荐
- bfs+hash poj 1077/hdu 1043 八数码问题
- 八数码问题 BFS+hash
- HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)
- 八数码问题,bfs,hash,康托
- POJ1077、HDU1043 Eight 八数码问题:双向BFS、A*
- hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数
- 由八数码问题引入。对BFS有更深考虑
- 【转载】八数码问题BFS与DFS的比较
- 搜索 ( 八数码问题详解:BFS,A*,IDA* )——Eight ( POJ 1077 )
- UVALive 6665 Dragon&#226;s Cruller --BFS,类八数码问题
- 由八数码问题引入。对BFS有更深考虑
- 历届试题 九宫重排 (bfs 八数码问题)
- 单向搜索bfs,PKU1077,八数码问题
- poj 1077--Eight(八数码问题,BFS,A*,全排列的哈希)
- 简单的八数码问题(BFS)
- 图算法_普通广度优先搜索(BFS)解八数码问题_C语言
- 特长生模拟 八数码(bfs+hash)
- 紫书p199 八数码(BFS,hash)
- BFS 八数码问题 typedef int State[9]; (BFS A*算法与优先队列)
- n数码问题,全排列的hash(转载