#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; //typedef int State[9]; //State st[10000000],goal; char str[10000000][10]; int st [1000000][10],goal[10]; char goa[10]; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; int dist[1000000]; int vis[362880], fact[9];//注意这里为什么要开362880大小,因为n!=∑i*i!(i从0到n-1),9!=362879. void init_lookup_table() { memset(vis, 0, sizeof(vis)); memset(fact, 0, sizeof(fact)); fact[0] = 1; for(int i = 1; i < 9; i++) fact[i] = fact[i - 1] * i; } int try_to_insert(int s) { int code = 0; for(int i = 0; i < 9; i++)//巧妙的编码过程!!注意理解这里! { int cnt = 0; for(int j = i + 1; j < 9; j++) if(st[s][j] < st[s][i]) cnt++; code += fact[8 - i] * cnt;//重点!!//不理解。 } if(vis[code]) return 0; return vis[code] = 1; } int bfs() { init_lookup_table(); int front=1,rear=2; while(front<rear) { if(memcmp(goal,st[front],sizeof(st[front]))==0) return front; int z; for(z=0;z<9;z++) if(st[front][z]==0) break; int x=z/3,y=z%3; for(int d=0;d<4;d++) { int newx=x+dx[d]; int newy=y+dy[d]; int newz=newx*3+newy; if(newx>=0&&newx<3&&newy>=0&&newy<3) { memcpy(st[rear],st[front], sizeof(st[front])); st[rear][newz] = st[front][z]; st[rear][z] = st[front][newz]; dist[rear]=dist[front]+1; if(try_to_insert(rear)) rear++; } } front++; } return 0; } int main() { int i; memset(dist,0,sizeof(dist)); scanf("%s",str[1]); scanf("%s",goa); int len1=strlen(str[1]); int len2=strlen(goa); for(i=0;i<len1;i++) { if(str[1][i]==‘.‘) st[1][i]=0; else st[1][i]=str[1][i]-‘0‘; } //for(i=0;i<len1;i++) // printf("%d ",st[1][i]); // printf("\n"); for(i=0;i<len2;i++) { if(goa[i]==‘.‘) goa[i]=0; else goal[i]=goa[i]-‘0‘; } // for(i=0;i<len1;i++) // printf("%d ",goal[i]); // printf("\n"); int ans=bfs(); if(ans>0) printf("%d\n",dist[ans]); else printf("-1\n"); return 0; } /* 12345678. 123.46758 3 */
原文:http://www.cnblogs.com/cancangood/p/4370077.html