A*算法 f(n)=g(n)+h(n)
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
int aim=1,vis[1000000];
int nxt[4][2]={-1,0,1,0,0,-1,0,1};
int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
char index[5]="udlr";
int cantor(int s[])
{
int sum=0;
for(int i=0;i<9;i++){
int num=0;
for(int j=i+1;j<9;j++)
if(s[j]<s[i]) num++;
sum+=(num*fac[9-i-1]);
}
return sum+1;
}
int get_h(int *a)
{
int sum=0;
for(int i=0;i<9;i++)
sum+=abs(a[i]-i-1);
return sum;
}
struct node
{
string path;
int loc;
int g,h;
int s[9];
int key;
bool operator < (const node&o)const{
return g+h>o.g+o.h;
}
};
priority_queue<node>que;
node fir;
bool check(int *a)
{
int sum=0;
for(int i=0;i<8;i++){
if(a[i]==9) continue;
for(int j=i+1;j<9;j++){
if(a[j]==9) continue;
if(a[i]>a[j]) sum++;
}
}
return sum%2 ? false : true;
}
void bfs()
{
memset(vis,0,sizeof(vis));
while(!que.empty()) que.pop();
fir.key=cantor(fir.s);
fir.g=0;
fir.h=get_h(fir.s);
vis[fir.key]=1;
que.push(fir);
while(!que.empty()){
node cur=que.top();
que.pop();
// cout<<cur.key<<endl;
if(cur.key==aim){
cout<<cur.path<<endl;
return;
}
int x=cur.loc/3;
int y=cur.loc%3;
for(int i=0;i<4;i++){
int tx=x+nxt[i][0];
int ty=y+nxt[i][1];
if(tx<0||ty<0||tx>2||ty>2) continue;
node Nxt=cur;
Nxt.loc=tx*3+ty;
Nxt.s[cur.loc]=Nxt.s[Nxt.loc];
Nxt.s[Nxt.loc]=9;
Nxt.key=cantor(Nxt.s);
Nxt.g+=1;
Nxt.h=get_h(Nxt.s);
if(!vis[Nxt.key]){
vis[Nxt.key]=1;
Nxt.path=Nxt.path+index[i];
if(Nxt.key==aim)
{
cout<<Nxt.path<<endl;
return;
}
que.push(Nxt);
}
}
}
}
int main()
{
char ch[2];
while(~scanf("%s",ch)){
if(ch[0]=='x'){ fir.s[0]=9; fir.loc=0; }
else{ fir.s[0]=ch[0]-'0';}
for(int i=1;i<9;i++){
scanf("%s",ch);
if(ch[0]=='x'){ fir.s[i]=9; fir.loc=i;}
else{ fir.s[i]=ch[0]-'0';}
}
if(!check(fir.s)) printf("unsolvable\n");
else bfs();
}
return 0;
}