2 12X453786 12345678X 564178X23 7568X4123
Case 1: 2 dd Case 2: 8 urrulldr
和之前做的八数码差不多
因为X的位置不同 多出了9倍的状态 所以才去保存路径的方式预处理答案
因为题目保证都是合法情况 不需要判断逆序数
然后和八数码差不多思路 不需要A* 直接广搜预处理即可
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<cmath> #include<map> #include<string> #define inf 1<<30 #define eps 1e-7 #define LD long double #define LL long long #define maxn 1000000005 using namespace std; int ed; int fac[3][3]= {{1,1,2},{6,24,120},{720,5040,40320}};//计算康拓值 struct node { int Map[3][3]; int x,y; int Hash; bool cheak() { if(x>=0&&x<3&&y>=0&&y<3) return true ; return false ; } } u,uu,v; int vis[9][400000];//标记 int pri[9][400000];//路径 int dir[4][2]= {{1,0},{0,-1},{0,1},{-1,0}}; 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; } char ch[5]= {"dlru"}; //输出路径 void print(int i) { int st=ed; int cnt=0,ans[1000]; while(pri[i][st]!=-2) { ans[cnt++]=vis[i][st]; st=pri[i][st]; } printf("%d\n",cnt); for(int i=cnt-1; i>=0; i--) printf("%c",ch[ans[i]]); printf("\n"); return ; } void bfs(int kind) { queue<node>que; que.push(u); pri[kind][u.Hash]=-2; while(!que.empty()) { uu=que.front(); que.pop(); for(int i=0; i<4; i++) { v=uu; v.x+=dir[i][0]; v.y+=dir[i][1]; if(v.cheak()) { swap(v.Map[v.x][v.y],v.Map[uu.x][uu.y]); v.Hash=get_hash(v.Map); if(pri[kind][v.Hash]==-1) { pri[kind][v.Hash]=uu.Hash; vis[kind][v.Hash]=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') u.Map[i][j]=0; else u.Map[i][j]=str[k]-'0'; k++; } u.x=kind/3; u.y=kind%3; u.Hash=get_hash(u.Map); bfs(kind); } int main() { int t; int tt=1; //预处理 memset(pri,-1,sizeof(pri)); 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); 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']); ed=get_hash(b); printf("Case %d: ",tt++); print(pos); } return 0; }