hdu1043(八数码问题,广搜 + hash(实现状态压缩) )
2014-01-28 21:49
375 查看
利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。
#include<iostream> #include<algorithm> #include<string> #include<stack> #include<queue> #include<map> #include<stdio.h> #include<stdlib.h> #include<ctype.h> #include<time.h> #include<math.h> #define eps 1e-9 #define N 400000 #define P system("pause") using namespace std; struct node { int map[9]; int zero; int hash_id; }; int fac[]={1,1,2,6,24,120,720,5040,40320}; int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //因为是逆序查找,所以上下左右,变成了 char dir[]={'d','u','r','l'}; //下上右左 int hash ; string path ; int cantor(int *s) //康拓扩展求hash值 { int count,i,j; int sum=0; for(i=0;i<8;i++){ count=0; for(j=i+1;j<9;j++) if(s[i]>s[j]) count++; sum+=(fac[8-i]*count); } return sum; } void bfs() { //从目标开始逆向搜索,枚举每种可能出现的排列 int i; node u,v; u.zero=8; u.map[8]=0; for(i=0;i<8;i++) u.map[i]=i+1; u.hash_id=cantor(u.map); hash[u.hash_id]=1; path[u.hash_id]=""; queue<node> q; q.push(u); while(!q.empty()) { u=q.front(); q.pop(); int x=u.zero/3; //找到0的位置 int y=u.zero%3; for(i=0;i<4;i++) { int nx=x+d[i][0]; int ny=y+d[i][1]; if(nx>=0 && nx<3 && ny>=0 && ny<3) { int k=nx*3+ny; //一维数组下标 v=u; v.zero=k; v.map[u.zero]=u.map[k]; v.map[k]=0; v.hash_id=cantor(v.map); } if(!hash[v.hash_id]) { hash[v.hash_id]=1; path[v.hash_id]=path[u.hash_id]; path[v.hash_id]+=dir[i]; q.push(v); } } } } int main() { //freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout);cc memset(hash,0,sizeof(hash)); bfs(); char c; int s[9]; while(cin>>c) { if(c=='x') s[0]=0; else s[0]=c-'0'; for(int i=1;i<9;i++) { cin>>c; if(c=='x') s[i]=0; else s[i]=c-'0'; } int k=cantor(s); if(!hash[k]) printf("unsolvable\n"); else{ string ss=path[k]; reverse(ss.begin(),ss.end()); cout<<ss<<endl; } } //P; return 0; }
相关文章推荐
- vijos1426兴奋剂检查(多维费用的背包问题+状态压缩+hash)
- 关于八数码问题中的状态判重的三种解决方法(编码、hash、<set>)
- hdu 1043-Eight(经典八数码问题)(单向广搜 A* 状态压缩)
- N皇后问题(状态压缩实现)
- 关于八数码问题中的状态判重的三种解决方法(编码、hash、<set>)
- poj 1077 Eight 八数码问题( 康拓展开+BFS状态压缩)
- vijos1426兴奋剂检查(多维费用的背包问题+状态压缩+hash)
- AStar解决八数码问题(java实现)
- Java实现Zip压缩与解压(解决中文乱码问题)
- 01背包问题-状态d[i][j],f[i][j],滚动数组--java实现
- n数码问题,全排列的hash(转载
- 源码编译apache实现CGI,虚拟主机,httpds安全访问,status服务状态信息,压缩等功能。
- 最小汉密尔顿回路问题 状态压缩dp
- 用C语言实现八数码问题
- HDU 4529 郑厂长系列故事——N骑士问题(dp,状态压缩)
- poj-1321 棋盘问题(状态压缩)
- uva 11195 Another queen (用状态压缩解决N后问题)
- 源代码:基于A*算法的八数码问题的实现(类的定义与实现)
- HDU 1043 Eight (经典八数码问题,BFS+状态枚举+伪哈希)
- A*算法来实现八数码的问题 C++