# Aizu ALDS1_13_B 8 Puzzle(八数码问题入门 BFS)

The goal of the 8 puzzle problem is to complete pieces on 3×33×3 cells where one of the cells is empty space.

In this problem, the space is represented by 0 and pieces are represented by integers from 1 to 8 as shown below.

1 3 0
4 2 5
7 8 6


You can move a piece toward the empty space at one step. Your goal is to make the pieces the following configuration in the shortest move (fewest steps).

1 2 3
4 5 6
7 8 0


Write a program which reads an initial state of the puzzle and prints the fewest steps to solve the puzzle.

## Input

The 3×33×3 integers denoting the pieces or space are given.

## Output

Print the fewest steps in a line.

## Constraints

• There is a solution.

## Sample Input

1 3 0
4 2 5
7 8 6


## Sample Output

4

1 2 3

4 5 6

7 8 0

（0表示空白格）

0只能和上下左右四个方向的数字交换位置

BFS

AC代码：

#include<stdio.h>
#include<string.h>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;

map<int,int> book;

int a[5][5];
int nx[4][2]={0,1,1,0,0,-1,-1,0};

struct node
{
int x,y,step;
int aa[5][5];
};

node getnode(int x,int y,int step,int aa[5][5])
{
node q;
q.x=x;
q.y=y;
q.step=step;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
q.aa[i][j]=aa[i][j];
}
}
return q;
}

void bfs(int x,int y,int step,int aa[5][5])
{
queue<node> q;
node p;
q.push(getnode(x,y,step,aa));
while(!q.empty())
{

for(int i=0;i<4;i++)
{
int tx=q.front().x+nx[i][0];
int ty=q.front().y+nx[i][1];
if(tx>=0&&tx<3&&ty>=0&&ty<3)
{
//memcpy(p.aa,q.front().aa,sizeof(q.front().aa));
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
p.aa[i][j]=q.front().aa[i][j];
}
}

//				printf("******\n");
//				for(int i=0;i<3;i++)
//				{
//					for(int j=0;j<3;j++)
//					{
//						printf("%d ",p.aa[i][j]);
//					}
//					printf("\n");
//				}
swap(p.aa[q.front().x][q.front().y],p.aa[tx][ty]);
int sum=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
sum=sum*10+p.aa[i][j];
}
}
//				printf("sum===%d\n",sum);

if(sum==123456780)
{
printf("%d\n",q.front().step+1);
return;
}

if(!book[sum])
{
book[sum]=1;
q.push(getnode(tx,ty,q.front().step+1,p.aa));
}
}
}
q.pop();
}
}

int main()
{
while(~scanf("%d%d%d",&a[0][0],&a[0][1],&a[0][2]))
{
for(int i=1;i<3;i++)
{
for(int j=0;j<3;j++)
{
scanf("%d",&a[i][j]);
}
}

int sum=0,x1,y1;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
sum=sum*10+a[i][j];
if(a[i][j]==0)
{
x1=i;
y1=j;
}
}
}
if(sum==123456780)
{
printf("0\n");
continue;
}
book.clear();
book[sum]=1;
bfs(x1,y1,0,a);
}
return 0;
}

/*
1 2 3
4 5 6
7 0 8

1 2 3
4 5 0
7 8 6
*/

# HDU 1043 八数码（八境界）

POJ提交记录（从下往上依次为第1,2,3,4,5,6,7,8境界）：

HDU提交记录（从下往上依次为第1,2,3,4,5,6,7,8境界）：

PS：因为HDU是多组测试数据，所以一般POJ上要100ms以上才能AC的方法，在HDU上是无法通过的（境界3除外）

map存路径，set判重，string存状态，毫无疑问，炸了。

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
#include<iostream>
using namespace std;

char input[1000];
int dir[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };
string d = "durl";
set<string>f;
map<string, string>m;
int sz = 0;

struct node
{
string s;
string path;
int pos;

node() {}
node(string str, string pa, int Pos)
{
s = str;
path = pa;
pos = Pos;
}
};

bool g(int a, int b)
{
if (a >= 0 && a <= 2 && b >= 0 && b <= 2) return 1;
return 0;
}

void pre()
{
queue<node>q;
q.push(node("12345678x", "", 8));
m["12345678x"] = "";
f.insert("12345678x");

while (!q.empty())
{
node h = q.front(); q.pop();
int a = h.pos / 3, b = h.pos % 3;
for (int i = 0; i<4; i++)
{
int x = a + dir[i][0], y = b + dir[i][1];
if (!g(x, y)) continue;
int pos = 3 * x + y;
swap(h.s[h.pos], h.s[pos]);
if (f.find(h.s) != f.end())
{
swap(h.s[h.pos], h.s[pos]);
continue;
}
q.push(node(h.s, d[i] + h.path, pos));
f.insert(h.s);
m[h.s] = d[i] + h.path;
swap(h.s[h.pos], h.s[pos]);
}
}

}

int main()
{
pre();
while(~scanf("%s",input))
{
string v="";
v = v + input[0];
for (int i = 1; i <= 8; i++)
{
scanf("%s", input);
v = v + input[0];
}
if (m[v] == "") cout << "unsolvable" << endl;
else cout << m[v] << endl;
}

return 0;
}

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;

char t[1000];
int c[10];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
char path[10]={'u','d','l','r'};
char op[5],input[20];
int ans;
stack<int>S;

struct Node
{
int s,p;
Node(){}
Node(int S,int P){s=S,p=P;}
};

struct Path
{
int from,dir;
}pa[400000];
bool f[400000];

int getnum()
{
int res=0;
for(int i=0;t[i];i++)
for(int j=i+1;t[j];j++)
if(t[j]<t[i]) res=res+c[8-i];
return res;
}

void getstr(int val)
{
int tmp[10],flag[10];
memset(flag,0,sizeof flag);
for(int i=0;i<9;i++) tmp[i]=val/c[8-i],val=val%c[8-i];
for(int i=0;i<9;i++)
{
int num=0;
for(int j=0;j<9;j++)
{
if(flag[j]==0) num++;
if(num==tmp[i]+1)
{
t[i]=j+'0'+1; if(t[i]=='9') t[i]='x';
flag[j]=1;break;
}
}
}
}

void bfs(int val,int Pos)
{
queue<Node>Q;
Q.push(Node(val,Pos));
f[val]=1; pa[val].from=-1,pa[val].dir=-1;

while(!Q.empty())
{
Node h=Q.front(); Q.pop();

if(h.s==0)
{
ans=1;
int now=h.s;
while(1)
{
if(pa[now].from==-1) break;
S.push(pa[now].dir);
now=pa[now].from;
}
break;
}

int a=h.p/3, b=h.p%3; getstr(h.s);

for(int i=0;i<4;i++)
{
int x=a+dir[i][0],y=b+dir[i][1];
if(!(x>=0&&x<=2&&y>=0&&y<=2)) continue;
int newpos=3*x+y;
swap(t[newpos],t[h.p]);
int news=getnum();
if(f[news]) {swap(t[newpos],t[h.p]);continue;}
pa[news].from=h.s, pa[news].dir=i, f[news]=1;
Q.push(Node(news,newpos));
swap(t[newpos],t[h.p]);
}
}
}

int main()
{
c[0]=1; for(int i=1;i<=8;i++) c[i]=c[i-1]*i;
while(~scanf("%s",op))
{
t[0]=op[0];
int pos;
for(int i=1;i<=8;i++)
{
scanf("%s",op); t[i]=op[0];
if(t[i]=='x') pos=i;
}
int state=getnum();

int sum=0;
for(int i=0;t[i];i++)
{
if(t[i]=='x') continue;
for(int j=0;j<i;j++)
{
if(t[j]=='x') continue;
if(t[i]<t[j]) sum++;
}
}

if(sum%2==1) { printf("unsolvable\n"); continue; }

ans=0;
memset(f,0,sizeof f);
bfs(state,pos);

while(!S.empty())
{
printf("%c",path[S.top()]);
S.pop();
}
printf("\n");

}
return 0;
}

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;

char t[1000];
int c[10];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
char path[10]={'d','u','r','l'};
char op[5],input[20];

struct Node
{
int s,p;
Node(){}
Node(int S,int P){s=S,p=P;}
};

struct Path
{
int from,dir;
}pa[400000];
bool f[400000];

int getnum()
{
int res=0;
for(int i=0;t[i];i++)
for(int j=i+1;t[j];j++)
if(t[j]<t[i]) res=res+c[8-i];
return res;
}

void getstr(int val)
{
int tmp[10],flag[10];
memset(flag,0,sizeof flag);
for(int i=0;i<9;i++) tmp[i]=val/c[8-i],val=val%c[8-i];
for(int i=0;i<9;i++)
{
int num=0;
for(int j=0;j<9;j++)
{
if(flag[j]==0) num++;
if(num==tmp[i]+1)
{
t[i]=j+'0'+1; if(t[i]=='9') t[i]='x';
flag[j]=1;break;
}
}
}
}

void pre()
{
queue<Node>Q;
Q.push(Node(0,8));
f[0]=1; pa[0].from=-1,pa[0].dir=-1;

while(!Q.empty())
{
Node h=Q.front(); Q.pop();
int a=h.p/3, b=h.p%3; getstr(h.s);
for(int i=0;i<4;i++)
{
int x=a+dir[i][0],y=b+dir[i][1];
if(!(x>=0&&x<=2&&y>=0&&y<=2)) continue;
int newpos=3*x+y;
swap(t[newpos],t[h.p]);
int news=getnum();
if(f[news]) {swap(t[newpos],t[h.p]);continue;}
pa[news].from=h.s, pa[news].dir=i, f[news]=1;
Q.push(Node(news,newpos));
swap(t[newpos],t[h.p]);
}
}
}

int main()
{
c[0]=1; for(int i=1;i<=8;i++) c[i]=c[i-1]*i;
pre();

while(~scanf("%s",op))
{
t[0]=op[0];
for(int i=1;i<=8;i++) {scanf("%s",op); t[i]=op[0];}
int state=getnum();
if(f[state]==0) printf("unsolvable\n");
else
{
while(1)
{
if(pa[state].from==-1) break;
printf("%c",path[pa[state].dir]);
state=pa[state].from;
}
printf("\n");
}
}
return 0;
}

HDU 不加无解判断剪枝会超时。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;

char input[1000],t[1000],op[5];
int c[10];
struct Node
{
int s,p;
Node(){}
Node(int S,int P){s=S,p=P;}
};
struct Path
{
int from,dir;
}path[400000];
int f[400000];

int dir[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };
string d[3] = {"","udlr","durl"};

queue<Node>q[3];
int ans;

stack<int>S;
queue<int>Q;

int getnum()
{
int res=0;
for(int i=0;t[i];i++)
for(int j=i+1;t[j];j++)
if(t[j]<t[i]) res=res+c[8-i];
return res;
}

void getstr(int val)
{
int tmp[10],flag[10];
memset(flag,0,sizeof flag);
for(int i=0;i<9;i++) tmp[i]=val/c[8-i],val=val%c[8-i];
for(int i=0;i<9;i++)
{
int num=0;
for(int j=0;j<9;j++)
{
if(flag[j]==0) num++;
if(num==tmp[i]+1)
{
t[i]=j+'0'+1; if(t[i]=='9') t[i]='x';
flag[j]=1;break;
}
}
}
}

bool g(int a, int b)
{
if (a >= 0 && a <= 2 && b >= 0 && b <= 2) return 1;
return 0;
}

void bfs(int now)
{
Node h=q[now].front(); q[now].pop();
int a=h.p/3,b=h.p%3;
getstr(h.s);

for(int i=0;i<4;i++)
{
int x=a+dir[i][0],y=b+dir[i][1];
if(!g(x,y)) continue;
int pos = 3 * x + y;

swap(t[h.p],t[pos]);

if(f[getnum()]==now) { swap(t[h.p],t[pos]); continue; }
else if(f[getnum()]!=0)
{
ans=1;
if(now==1)
{
S.push(i);
int u=h.s;
while(path[u].from!=-1) { S.push(path[u].dir); u=path[u].from; }
u=getnum();
while(path[u].from!=-1) { Q.push(path[u].dir); u=path[u].from; }
}
else
{
Q.push(i);
int u=h.s;
while(path[u].from!=-1) { Q.push(path[u].dir); u=path[u].from; }
u=getnum();
while(path[u].from!=-1) { S.push(path[u].dir); u=path[u].from; }
}
break;
}
else
{
f[getnum()]=now;
path[getnum()].from=h.s;
path[getnum()].dir=i;
q[now].push(Node(getnum(),pos));
swap(t[h.p],t[pos]);
}
}
}

{
t[0]=op[0];
for(int i=1;i<=8;i++)
{scanf("%s",op); t[i]=op[0];}
for(int i=0;i<=9;i++) input[i]=t[i];
}

void init()
{
memset(f,ans=0,sizeof f);
while(!q[1].empty()) q[1].pop();
while(!q[2].empty()) q[2].pop();
}

void work(int s,int pos)
{
q[1].push(Node(s,pos)); q[2].push(Node(0,8));
f[s]=1; path[s].from=path[s].dir=-1;
f[0]=2; path[0].from=path[0].dir=-1;
while((!q[1].empty())&&(!q[2].empty()))
{
if(ans==1) break;
bfs(1); if(ans==1) break;
bfs(2); if(ans==1) break;
}
}

int main()
{
c[0]=1; for(int i=1;i<=8;i++) c[i]=c[i-1]*i;
while(~scanf("%s",op))
{

int sum=0;
for(int i=0;t[i];i++)
{
if(t[i]=='x') continue;
for(int j=0;j<i;j++)
{
if(t[j]=='x') continue;
if(t[i]<t[j]) sum++;
}
}

if(sum%2==1)
{
printf("unsolvable\n");
continue;
}
init();
for(int i=0;i<9;i++)
if(input[i]=='x'){work(getnum(),i); break; }
if(ans==1)
{
while(!S.empty()) { printf("%c",d[1][S.top()]); S.pop(); }
while(!Q.empty()) { printf("%c",d[2][Q.front()]); Q.pop(); }
}
else printf("unsolvable");
printf("\n");
}
return 0;
}

g(n)是深度，即从初始到目前的操作次数，h(n)是简单估价函数，表示目前状态与最终状态同一位置不同数字的个数。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;

char input[1000],t[1000],op[5];
int c[10];
struct Node
{
int s,p;
int f,g,h;
Node(){}
Node(int S,int P,int G,int H)
{
s=S,p=P;
g=G,h=H;
f=g+h;
}
bool operator < (const Node &a) const {
return f>a.f;
}
};

struct Path
{
int from,dir;
}path[400000];
int flag[400000];
int G[400000];

int dir[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };
string d = "udlr";

priority_queue<Node>Q;
int ans;

stack<int>S;

int getnum()
{
int res=0;
for(int i=0;t[i];i++)
for(int j=i+1;t[j];j++)
if(t[j]<t[i]) res=res+c[8-i];
return res;
}

void getstr(int val)
{
int tmp[10],flag[10];
memset(flag,0,sizeof flag);
for(int i=0;i<9;i++) tmp[i]=val/c[8-i],val=val%c[8-i];
for(int i=0;i<9;i++)
{
int num=0;
for(int j=0;j<9;j++)
{
if(flag[j]==0) num++;
if(num==tmp[i]+1)
{
t[i]=j+'0'+1; if(t[i]=='9') t[i]='x';
flag[j]=1;break;
}
}
}
}

bool g(int a, int b)
{
if (a>=0 && a<=2 && b>=0 && b<=2) return 1;
return 0;
}

{
t[0]=op[0];
for(int i=1;i<=8;i++) {scanf("%s",op); t[i]=op[0];}
for(int i=0;i<=9;i++) input[i]=t[i];
}

void init()
{
memset(G,-1,sizeof G);
memset(flag,0,sizeof flag);
while(!Q.empty()) Q.pop();
}

int H(int val)
{
char tmp[10];
for(int i=0;i<=9;i++) tmp[i]=t[i];

getstr(val);

int res=0;
for(int i=0;i<9;i++)
{
if(i<8) if(t[i]-'0'!=i+1) res++;
if(i==8&&t[i]!='x') res++;
}

for(int i=0;i<=9;i++) t[i]=tmp[i];
return res;
}

void A_star(int s,int pos)
{
flag[s]=2; G[s]=0;
path[s].from=-1;
path[s].dir=-1;
Q.push(Node(s,pos,0,H(s)));
while(!Q.empty())
{
Node h=Q.top(); Q.pop(); flag[h.s]=2;
getstr(h.s);
if(h.s==0)
{
ans=1; int now=h.s;
while(1)
{
if(path[now].from==-1) return;
S.push(path[now].dir);
now=path[now].from;
}
}

int a=h.p/3,b=h.p%3;

for(int i=0;i<4;i++)
{
int x=a+dir[i][0],y=b+dir[i][1];
if(!g(x,y)) continue;
int newpos=3*x+y;

swap(t[h.p],t[newpos]);
int news=getnum();
swap(t[h.p],t[newpos]);

if(flag[news]==0||(flag[news]==1&&h.g+1<G[news]))
{
flag[news]=1; G[news]=h.g+1;
path[news].from=h.s;
path[news].dir=i;
Q.push(Node(news,newpos,h.g+1,H(news)));
}
}
}
}

int main()
{
c[0]=1; for(int i=1;i<=8;i++) c[i]=c[i-1]*i;
while(~scanf("%s",op))
{
int sum=0;
for(int i=0;t[i];i++)
{
if(t[i]=='x') continue;
for(int j=0;j<i;j++)
{
if(t[j]=='x') continue;
if(t[i]<t[j]) sum++;
}
}

if(sum%2==1)
{
printf("unsolvable\n");
continue;
}
init();

for(int i=0;i<9;i++)
if(input[i]=='x'){A_star(getnum(),i); break; }
while(!S.empty()){printf("%c",d[S.top()]); S.pop();}
printf("\n");
}
return 0;
}

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;

char input[1000],t[1000],op[5];
int c[10];
struct Node
{
int s,p;
int f,g,h;
Node(){}
Node(int S,int P,int G,int H)
{
s=S,p=P;
g=G,h=H;
f=g+h;
}
};

struct Path
{
int from,dir;
}path[400000];
int flag[400000];
int G[400000];

int dir[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };
string d = "udlr";

queue<Node>Q;
int ans;

stack<int>S;

int getnum()
{
int res=0;
for(int i=0;t[i];i++)
for(int j=i+1;t[j];j++)
if(t[j]<t[i]) res=res+c[8-i];
return res;
}

void getstr(int val)
{
int tmp[10],flag[10];
memset(flag,0,sizeof flag);
for(int i=0;i<9;i++) tmp[i]=val/c[8-i],val=val%c[8-i];
for(int i=0;i<9;i++)
{
int num=0;
for(int j=0;j<9;j++)
{
if(flag[j]==0) num++;
if(num==tmp[i]+1)
{
t[i]=j+'0'+1; if(t[i]=='9') t[i]='x';
flag[j]=1;break;
}
}
}
}

bool g(int a, int b)
{
if (a>=0 && a<=2 && b>=0 && b<=2) return 1;
return 0;
}

{
t[0]=op[0];
for(int i=1;i<=8;i++) {scanf("%s",op); t[i]=op[0];}
for(int i=0;i<=9;i++) input[i]=t[i];
}

void init()
{
memset(G,-1,sizeof G);
memset(flag,0,sizeof flag);
while(!Q.empty()) Q.pop();
}

int H(int val)
{
char tmp[10];
for(int i=0;i<=9;i++) tmp[i]=t[i];

getstr(val);

int res=0;

for(int i=0;i<9;i++)
{
if(t[i]=='x') continue;

int num=t[i]-'0'-1;
int a=i/3,b=i%3;
int x=num/3,y=num%3;

res=res+abs(a-x)+abs(b-y);
}

for(int i=0;i<=9;i++) t[i]=tmp[i];
return res;
}

void A_star(int s,int pos)
{
flag[s]=2; G[s]=0;
path[s].from=-1;
path[s].dir=-1;
Q.push(Node(s,pos,0,H(s)));
while(!Q.empty())
{
Node h=Q.front(); Q.pop(); flag[h.s]=2;
getstr(h.s);
if(h.s==0)
{
ans=1; int now=h.s;
while(1)
{
if(path[now].from==-1) return;
S.push(path[now].dir);
now=path[now].from;
}
}

int a=h.p/3,b=h.p%3;

for(int i=0;i<4;i++)
{
int x=a+dir[i][0],y=b+dir[i][1];
if(!g(x,y)) continue;
int newpos=3*x+y;

swap(t[h.p],t[newpos]);
int news=getnum();
swap(t[h.p],t[newpos]);

if(flag[news]==0||(flag[news]==1&&h.g+1<G[news]))
{
flag[news]=1; G[news]=h.g+1;
path[news].from=h.s;
path[news].dir=i;
Q.push(Node(news,newpos,h.g+1,H(news)));
}
}
}
}

int main()
{
c[0]=1; for(int i=1;i<=8;i++) c[i]=c[i-1]*i;
while(~scanf("%s",op))
{
int sum=0;
for(int i=0;t[i];i++)
{
if(t[i]=='x') continue;
for(int j=0;j<i;j++)
{
if(t[j]=='x') continue;
if(t[i]<t[j]) sum++;
}
}

if(sum%2==1)
{
printf("unsolvable\n");
continue;
}
init();
for(int i=0;i<9;i++)
if(input[i]=='x'){A_star(getnum(),i); break; }

while(!S.empty()){printf("%c",d[S.top()]); S.pop();}
printf("\n");
}
return 0;
}

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;

char input[1000],t[1000],op[5];
int c[10];
struct Node
{
int s,p;
int f,g,h;
Node(){}
Node(int S,int P,int G,int H)
{
s=S,p=P;
g=G,h=H;
f=g+h;
}
bool operator < (const Node &a) const {
return f>a.f;
}
};

struct Path
{
int from,dir;
}path[400000];
int flag[400000];
int G[400000];

int dir[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };
string d = "udlr";

priority_queue<Node>Q;
int ans;

stack<int>S;

int getnum()
{
int res=0;
for(int i=0;t[i];i++)
for(int j=i+1;t[j];j++)
if(t[j]<t[i]) res=res+c[8-i];
return res;
}

void getstr(int val)
{
int tmp[10],flag[10];
memset(flag,0,sizeof flag);
for(int i=0;i<9;i++) tmp[i]=val/c[8-i],val=val%c[8-i];
for(int i=0;i<9;i++)
{
int num=0;
for(int j=0;j<9;j++)
{
if(flag[j]==0) num++;
if(num==tmp[i]+1)
{
t[i]=j+'0'+1; if(t[i]=='9') t[i]='x';
flag[j]=1;break;
}
}
}
}

bool g(int a, int b)
{
if (a>=0 && a<=2 && b>=0 && b<=2) return 1;
return 0;
}

{
t[0]=op[0];
for(int i=1;i<=8;i++) {scanf("%s",op); t[i]=op[0];}
for(int i=0;i<=9;i++) input[i]=t[i];
}

void init()
{
memset(G,-1,sizeof G);
memset(flag,0,sizeof flag);
while(!Q.empty()) Q.pop();
}

int H(int val)
{
char tmp[10];
for(int i=0;i<=9;i++) tmp[i]=t[i];

getstr(val);

int res=0;

for(int i=0;i<9;i++)
{
if(t[i]=='x') continue;

int num=t[i]-'0'-1;
int a=i/3,b=i%3;
int x=num/3,y=num%3;

res=res+abs(a-x)+abs(b-y);
}

for(int i=0;i<=9;i++) t[i]=tmp[i];
return res;
}

void A_star(int s,int pos)
{
flag[s]=2; G[s]=0;
path[s].from=-1;
path[s].dir=-1;
Q.push(Node(s,pos,0,H(s)));
while(!Q.empty())
{
Node h=Q.top(); Q.pop(); flag[h.s]=2;
getstr(h.s);
if(h.s==0)
{
ans=1; int now=h.s;
while(1)
{
if(path[now].from==-1) return;
S.push(path[now].dir);
now=path[now].from;
}
}

int a=h.p/3,b=h.p%3;

for(int i=0;i<4;i++)
{
int x=a+dir[i][0],y=b+dir[i][1];
if(!g(x,y)) continue;
int newpos=3*x+y;

swap(t[h.p],t[newpos]);
int news=getnum();
swap(t[h.p],t[newpos]);

if(flag[news]==0||(flag[news]==1&&h.g+1<G[news]))
{
flag[news]=1; G[news]=h.g+1;
path[news].from=h.s;
path[news].dir=i;
Q.push(Node(news,newpos,h.g+1,H(news)));
}
}
}
}

int main()
{
c[0]=1; for(int i=1;i<=8;i++) c[i]=c[i-1]*i;
while(~scanf("%s",op))
{
int sum=0;
for(int i=0;t[i];i++)
{
if(t[i]=='x') continue;
for(int j=0;j<i;j++)
{
if(t[j]=='x') continue;
if(t[i]<t[j]) sum++;
}
}

if(sum%2==1)
{
printf("unsolvable\n");
continue;
}
init();
for(int i=0;i<9;i++)
if(input[i]=='x'){A_star(getnum(),i); break; }

while(!S.empty()){printf("%c",d[S.top()]); S.pop();}
printf("\n");
}
return 0;
}

IDA*策略占用空间极小，一般情况下效率会比A*高。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;

char input[1000],t[1000],op[5];
int c[10];
int dir[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };
string d = "udlr";
int flag,limit,length;
int path[1000];

int getnum()
{
int res=0;
for(int i=0;t[i];i++)
for(int j=i+1;t[j];j++)
if(t[j]<t[i]) res=res+c[8-i];
return res;
}

void getstr(int val)
{
int tmp[10],flag[10];
memset(flag,0,sizeof flag);
for(int i=0;i<9;i++) tmp[i]=val/c[8-i],val=val%c[8-i];
for(int i=0;i<9;i++)
{
int num=0;
for(int j=0;j<9;j++)
{
if(flag[j]==0) num++;
if(num==tmp[i]+1)
{
t[i]=j+'0'+1; if(t[i]=='9') t[i]='x';
flag[j]=1;break;
}
}
}
}

bool g(int a, int b)
{
if (a>=0 && a<=2 && b>=0 && b<=2) return 1;
return 0;
}

{
t[0]=op[0];
for(int i=1;i<=8;i++) {scanf("%s",op); t[i]=op[0];}
for(int i=0;i<=9;i++) input[i]=t[i];
}

int H(int val)
{
char tmp[10];
for(int i=0;i<=9;i++) tmp[i]=t[i];
getstr(val); int res=0;

for(int i=0;i<9;i++)
{
if(t[i]=='x') continue;

int num=t[i]-'0'-1;
int a=i/3,b=i%3;
int x=num/3,y=num%3;
res=res+abs(a-x)+abs(b-y);
}

for(int i=0;i<=9;i++) t[i]=tmp[i];
return res;
}

void dfs(int pos,int s,int deep,int pre_dir)
{
if(s==0)
{
length=deep;
flag=1;return;
}
if(deep+H(s)>limit) return;

char u[10]; getstr(s);
for(int i=0;i<=9;i++) u[i]=t[i];

int a=pos/3,b=pos%3;
for(int i=0;i<4;i++)
{
if(pre_dir==0&&i==1) continue;
if(pre_dir==1&&i==0) continue;
if(pre_dir==2&&i==3) continue;
if(pre_dir==3&&i==2) continue;

int x=a+dir[i][0],y=b+dir[i][1];
if(!g(x,y)) continue;

int new_pos=3*x+y;

swap(u[pos],u[new_pos]); for(int i=0;i<=9;i++) t[i]=u[i];
int new_s=getnum(); path[deep]=i;
dfs(new_pos,new_s,deep+1,i); if(flag) return;
swap(u[pos],u[new_pos]);
}

}

int main()
{
c[0]=1; for(int i=1;i<=8;i++) c[i]=c[i-1]*i;
while(~scanf("%s",op))
{

int sum=0;
for(int i=0;t[i];i++)
{
if(t[i]=='x') continue;
for(int j=0;j<i;j++)
{
if(t[j]=='x') continue;
if(t[i]<t[j]) sum++;
}
}

if(sum%2==1) { printf("unsolvable\n"); continue; }

for(int i=0;i<9;i++)
{
if(input[i]!='x') continue;
limit=H(getnum()); flag=0;
while(!flag)
{
for(int i=0;i<=9;i++) t[i]=input[i];

int ggg=getnum();
dfs(i,ggg,0,-1);

if(flag) break;
limit++;
}

for(int i=0;i<limit;i++) printf("%c",d[path[i]]);
printf("\n");
}
}
return 0;
}