转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents
by---cxlove
八数码的升级版,给定起点,终点,双向BFS可破。有了魔板那题的基础。
同样对这题进行预处理,不过需要注意的是,这题有不同的情况,也就是空位X造成的,所以枚举X的位置,9种置换,进行BFS。
对于每一种起点,保存所有的能到达状态的路径。
跑了近1S左右。HASH依旧是康托展开
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> #include<string> #include<vector> #include<algorithm> #include<map> #include<set> #define inf 1<<30 #define LL long long #define maxn 1<<24 using namespace std; struct Node{ int a[3][3]; int val; int x,y; bool check(){ if(x>=0&&x<3&&y>=0&&y<3) return true; return false; } }tmp,u,v; int fac[3][3]={{1,1,2},{6,24,120},{720,5040,40320}}; int pre[9][370000]; char ope[9][370000]; int way[4][2]={{1,0},{0,-1},{0,1},{-1,0}}; bool flag[370000]; int get_hash(int maze[3][3]){ int ret=0; for(int i=0;i<3;i++) for(int j=0;j<3;j++){ int cnt=0; for(int a=0;a<i;a++) for(int b=0;b<3;b++) if(maze[a][b]>maze[i][j]) cnt++; for(int b=0;b<j;b++) if(maze[i][b]>maze[i][j]) cnt++; ret+=cnt*fac[i][j]; } return ret; } void bfs(int kind){ queue<Node>que; que.push(tmp); pre[kind][tmp.val]=-2; flag[tmp.val]=true; while(!que.empty()){ u=que.front(); que.pop(); for(int i=0;i<4;i++){ v=u; v.x+=way[i][0]; v.y+=way[i][1]; if(v.check()){ swap(v.a[v.x][v.y],v.a[u.x][u.y]); v.val=get_hash(v.a); if(pre[kind][v.val]==-1){ flag[v.val]=true; pre[kind][v.val]=u.val; ope[kind][v.val]=i; que.push(v); } } } } } void Init(char *str,int kind){ int k=0; for(int i=0;i<3;i++) for(int j=0;j<3;j++){ if(str[k]=='X') tmp.a[i][j]=0; else tmp.a[i][j]=str[k]-'0'; k++; } tmp.x=kind/3;tmp.y=kind%3; tmp.val=get_hash(tmp.a); bfs(kind); } char ch[5]={"dlru"}; int main(){ memset(pre,-1,sizeof(pre)); memset(flag,false,sizeof(flag)); Init("X12345678",0); Init("1X2345678",1); Init("12X345678",2); Init("123X45678",3); Init("1234X5678",4); Init("12345X678",5); Init("123456X78",6); Init("1234567X8",7); Init("12345678X",8); int t,cas=0; scanf("%d",&t); while(t--){ char s1[10],s2[10]; scanf("%s%s",s1,s2); int a[3][3],b[3][3],pos,c[9],k=1; for(int i=0;i<9;i++){ if(s1[i]=='X'){ c[0]=0; pos=i; } else c[s1[i]-'0']=k++; } for(int i=0;i<9;i++) b[i/3][i%3]=(s2[i]=='X'?c[0]:c[s2[i]-'0']); int temp=get_hash(b); int cnt=0,ans[1000]; while(pre[pos][temp]!=-2){ ans[cnt++]=ope[pos][temp]; temp=pre[pos][temp]; } printf("Case %d: %d\n",++cas,cnt); for(int i=cnt-1;i>=0;i--) printf("%c",ch[ans[i]]); printf("\n"); } return 0; }