poj 1077 bfs+hash(康托扩展)
八数码问题:bfs实现....
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <algorithm> 6 #include <cmath> 7 #include <queue> 8 9 using namespace std; 10 11 #define MAXN 363000 //9!==326880 12 13 struct node 14 { 15 int s[9];//当前状态 16 int loc;//'0'的位置。。。即'x'的位置 17 int stat;//康托展开的hash值 18 string path;//路径 19 }; 20 int fac[]={1,1,2,6,24,120,720,5040,40320,362880};// 21 // 0!1!2!3!4! 5! 6! 7! 8! 9! 22 int dir[4][2]={-1,0,1,0,0,-1,0,1};//udlr 23 char index[5]="udlr"; 24 int aim=322561;//123456780对应的hash值 25 string path;//路径 26 bool vis[MAXN]; 27 node st; 28 29 int cantor(const int *s){ //康托展开求序列的hash值 30 int sum=0; 31 for(int i=0;i<9;i++){ 32 int num=0; 33 for(int j=0;j<i;j++) 34 if(s[j]>s[i]) 35 num++; 36 sum+=(num*fac[i]); 37 } 38 return sum+1; 39 } 40 41 bool isok(int x,int y) 42 { 43 if(x<0 || x>2 || y>2 || y<0) 44 return false; 45 return true; 46 } 47 48 bool bfs() 49 { 50 memset(vis,0,sizeof(vis)); 51 queue<node>q; 52 node cur,tmp; 53 q.push(st); 54 vis[st.stat]=1; 55 while(!q.empty()) 56 { 57 cur=q.front(); 58 q.pop(); 59 int x=cur.loc/3,y=cur.loc%3; 60 for(int i=0;i<4;i++) 61 { 62 int tx=x+dir[i][0],ty=y+dir[i][1]; 63 if(!isok(tx,ty)) 64 continue; 65 tmp=cur; 66 tmp.loc=tx*3+ty;//'0'移动到该位置 67 tmp.s[cur.loc]=tmp.s[tmp.loc];//操作,把现在的'0'的原值移动到原图的'0'位置处 68 tmp.s[tmp.loc]=0; 69 tmp.stat=cantor(tmp.s);//取hash 70 if(!vis[tmp.stat]) 71 { 72 vis[tmp.stat]=1; 73 tmp.path=cur.path+index[i]; 74 if(tmp.stat==aim) 75 { 76 path=tmp.path; 77 return true; 78 } 79 q.push(tmp); 80 } 81 } 82 } 83 return 0; 84 } 85 86 int main() 87 { 88 char buf[256]; 89 while(gets(buf)) 90 { 91 int len=strlen(buf); 92 int cnt=0; 93 for(int i=0;i<len;i++) 94 { 95 if(buf[i]>='1' && buf[i]<='9') 96 { 97 st.s[cnt++]=buf[i]-'0'; 98 } 99 else if(buf[i]=='x') 100 { 101 st.s[cnt]=0; 102 st.loc=cnt++; 103 } 104 } 105 st.stat=cantor(st.s); 106 if(st.stat==aim) 107 { 108 puts(""); 109 continue; 110 } 111 if(bfs()) 112 cout<<path<<endl; 113 else 114 puts("unsolvable"); 115 } 116 return 0; 117 }