利用康拓展开可以实现没有重复的hash判重。
用 pre[i] 数组存储上一步 i 。
用 walk[i] 数组存储从 pre[i] 到 i 的方向。
/* title :Eight status:AC by wf,2016.1.10 */ #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <stack> #include <cmath> #include <queue> #include <set> #include <map> #define FOR(i,s,t) for(int i = (s) ; i <= (t) ; ++i ) typedef long long ll; typedef unsigned long long ull; using namespace std; const int inf=0x3f3f3f3f; const int maxn=1e6+5; int f[9]= {40320,5040,720,120,24,6,2,1,1}; char dir[4][2]= {-1,0,1,0,0,-1,0,1}; char tab[4]= {'d','u','r','l'}; bool vis[maxn]; char next[maxn]; int pre[maxn]; char walk[maxn]; struct node { int x, y,num[3][3]; }; int tmp[9]; int GetHash(int num[3][3]) { int index=0; for(int i=0;i<3;++i) { for(int j=0;j<3;++j) { tmp[index++] = num[i][j]; } } int ret=0; for(int i=0; i<9; ++i) { int t=0; for(int j=i+1; j<9; ++j) { if( tmp[j] < tmp[i] )t++; } ret += f[i]*t; } return ret; } queue<node>q; void bfs() { node now,next; now.x=2; now.y=2; int index=1; for(int i=0; i<3; ++i) { for(int j=0; j<3; ++j) { now.num[i][j]=index++; } } //int key = GetHash(now.num); //cout<<"debug key=="<<key<<endl; while(!q.empty())q.pop(); q.push(now); while(!q.empty()) { now = q.front(); q.pop(); int key = GetHash(now.num); vis[key]=1; for(int i=0; i<4; ++i) { int nx=now.x+dir[i][0]; int ny=now.y+dir[i][1]; if(nx<0 || nx>=3)continue; if(ny<0 || ny>=3)continue; swap(now.num[now.x][now.y] , now.num[nx][ny]); int key2 = GetHash(now.num); if( !vis[key2] ) { next.x=nx; next.y=ny; for(int i=0;i<3;++i) { for(int j=0;j<3;++j) { next.num[i][j]=now.num[i][j]; } } pre[key2]=key; walk[key2]=tab[i]; q.push(next); } swap(now.num[now.x][now.y] , now.num[nx][ny]); } } } int main() { //#ifndef ONLINE_JUDGE //freopen("in.txt","r",stdin); //#endif memset(vis,0,sizeof 0); bfs(); char mp[9]; while(cin>>mp[0]) { for(int i=1;i<9;++i) { cin>>mp[i]; } int index=0,num[3][3]; for(int i=0;i<3;++i) { for(int j=0;j<3;++j) { if(mp[index]=='x')mp[index]='9'; num[i][j] = mp[index++] - '0'; } } int key = GetHash(num); if( !vis[key] ) { cout<<"unsolvable"<<endl; continue; } while(key!=0) { cout<<walk[key]; key=pre[key]; } cout<<endl; } }