HDU 1043 八数码 反向BFS+康拓展开
2017-07-16 22:13
351 查看
题意
八数码,末状态”12345678x”题解
POJ八数码用普通BFS+康拓展开过了。但是HDU1043却过不了,看了题解才知道要反向BFS打表。有关康拓展开,可以参考相关百度文库文档。反向BFS的思路就是从末状态开始BFS搜索到达所有状态的路径,八数码问题总共也就三十多万个状态,每个状态路径可以用string进行存储,并使用康拓展开进行编码。针对每一组数据,进行编码后直接到string数组中查找即可。代码
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<string> #include<strstream> #define INF 1e9 using namespace std; typedef int State[9]; State tar={1,2,3,4,5,6,7,8,9}; const int maxState=400000; bool vis[maxState]; string path[maxState]; int fact[10]; int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; void init(){ memset(vis,false,sizeof(vis)); fact[0]=1; for(int i=1;i<9;i++){ fact[i]=fact[i-1]*i; } } string addDir(int i){ if(i==0) return "l"; if(i==1) return "r"; if(i==2) return "u"; if(i==3) return "d"; } int calCode(State news){ int code=0; for(int i=0;i<9;i++){ int cnt=0; for(int j=i+1;j<9;j++){ if(news[j]<news[i]){ cnt++; } } code+=fact[8-i]*cnt; } return code; } int bfs(){ init(); queue<int> que; que.push(123456789); while(!que.empty()){ int ft=que.front(); que.pop(); State s; for(int i=8;i>=0;i--){ s[i]=ft%10; ft/=10; } int z=-1; for(int i=0;i<9;i++){ if(s[i]==9){ z=i; break; } } int x=z/3,y=z%3; for(int i=0;i<4;i++){ State news; int newx=x+dir[i][0]; int newy=y+dir[i][1]; int newz=newx*3+newy; if(newx<0||newy<0||newx>=3||newy>=3) continue; memcpy(&news,&s,sizeof(s)); news[newz]=s[z]; news[z]=s[newz]; int code=calCode(news); if(vis[code]) continue; else{ vis[code]=true; path[code]=path[calCode(s)]+addDir(i); int sum=0; for(int i=0;i<9;i++){ sum=sum*10+news[i]; } que.push(sum); } } } return 0; } int main() { bfs(); char s[100]; for(int i=0;i<400000;i++){ reverse(path[i].begin(),path[i].end()); } while(cin.getline(s,50)){ State st; int pos=0; for(int i=0;i<strlen(s);i++){ if(pos==9) break; if(s[i]==' ') continue; if(s[i]=='x') st[pos++]=9; else st[pos++]=s[i]-'0'; } int rev1=0; for(int i=0;i<9;i++){ if(st[i]==9) continue; for(int j=0;j<i;j++){ if(st[j]==9) continue; if(st[j]>st[i]){ rev1++; } } } if(rev1%2!=0) cout<<"unsolvable"<<endl; else{ cout<<path[calCode(st)]<<endl; } } return 0; }
相关文章推荐
- HDU-1043:Eight(八数码+bfs(反向或A*))
- HDU 1043 八数码
- 八数码问题(HDU 1043)
- HDU 1043 Eight(八数码第五境界|A*+哈希+简单估价函数+打表)
- hdu 1043 八数码问题-A*搜索
- HDU 1043 Eight(经典八数码问题)对比POJ 1077
- 八数码 HDU - 1043(状态压缩,宽搜)
- HDU 1043 Eight ((八数码问题)逆向BFS + 康托定理判重)
- hdu 1043 Eight(8数码,第三重)
- HDU-1043 Eight 八数码问题
- HDU1043 Eight 八数码问题
- poj 1077 hdu 1043 Eight 八数码问题 DBFS(双向广度优先搜索)a*算法 康拓展开
- HDU 1043 八数码(经典搜索Astar+康托展开)
- 八数码A*【POJ-1077 HDU-1043】
- hdu 1043 八数码--打表
- hdu 1043 八数码问题
- hdu 1043 Eight 经典八数码问题
- 八数码问题——HDU 1043
- poj 1077 zoj 1217 hdu 1043 八数码
- HDU 1043 八数码问题的多种解法