Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 11025 | Accepted: 4850 | Special Judge |
Description
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
r-> d-> r->
Input
1 2 3
x 4 6
7 5 8
1 2 3 x 4 6 7 5 8
Output
Sample Input
2 3 4 1 5 x 7 6 8
Sample Output
ullddrurdllurdruldr
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=400000;
struct Node
{
int state[3][3];//当天状态
int x,y;//9的位置
int n;//节点序号
};
Node pre,end;//初始状态和目标状态
int n1,n2;//记录正向和反向分别所走的节点个数
int vis1[maxn],vis2[maxn];//记录正向和反向的节点序号
struct Path
{
int pre;//父亲节点
int dir;//方向
};
Path path1[maxn],path2[maxn];//1表示头,2表示尾
int xx[4]={-1,1,0,0};
int yy[4]={0,0,-1,1};
char dir1[5]="udlr",dir2[5]="durl";//正向和反向的方向
int fac[10];
int hash(int a[][3])//逆序数哈希
{
int sum = 0,cnt;
for(int i=1;i<9;i++)
{
cnt = 0;
for(int j=0;j<i;j++)
{
if(a[j/3][j%3]>a[i/3][i%3])
cnt ++;
}
sum += cnt*fac[i];
}
return sum;
}
void init()//初始化
{
fac[0]=1;
for(int i=1;i<10;i++) fac[i]=i*fac[i-1];
n1=n2=0;//impor
memset(vis1,0,sizeof(vis1));memset(vis2,0,sizeof(vis2));
for(int i=0;i<9;i++) end.state[i/3][i%3]=i+1;
end.x=end.y=2;//初始化目标状态
for(int i=0;i<9;i++)
{
char ch;cin>>ch;
if(ch=='x') ch='9',pre.x=i/3,pre.y=i%3;
pre.state[i/3][i%3]=ch-'0';
}//初始化初始状态
}
bool in(int x,int y)
{
return (x>=0 && x<3 && y>=0 && y<3);
}
int bfs()
{
queue<Node> P,Q;//Q表示正向搜索,P表示反向搜索
pre.n=end.n=0;
P.push(pre),Q.push(end);//P表示头,Q表示尾
vis1[hash(pre.state)]=vis2[hash(end.state)]=1;//1表示头,2表示尾
while(!P.empty()&&!Q.empty())
{
if(!P.empty())
{
Node top=P.front();P.pop();
int tmp=top.n;
for(int i=0;i<4;i++)
{
int tx=top.x+xx[i],ty=top.y+yy[i];
if(in(tx,ty))
{
swap(top.state[top.x][top.y],top.state[tx][ty]);
swap(tx, top.x), swap(ty, top.y);
int v=hash(top.state);
if(vis2[v])
{
path1[++n1].pre=tmp;
path1[n1].dir=i;
n2=vis2[v]-1;
return 1;
}
if(!vis1[v])
{
top.n=++n1;
path1[n1].pre=tmp;
path1[n1].dir=i;
vis1[v]=1+n1;
P.push(top);
}
swap(tx, top.x), swap(ty, top.y);
swap(top.state[top.x][top.y],top.state[tx][ty]);
}
}
}
if(!Q.empty())
{
Node top=Q.front();Q.pop();
int tmp=top.n;
for(int i=0;i<4;i++)
{
int tx=top.x+xx[i],ty=top.y+yy[i];
if(in(tx,ty))
{
swap(top.state[top.x][top.y],top.state[tx][ty]);
swap(tx, top.x), swap(ty, top.y);
int v=hash(top.state);
if(vis1[v])
{
path2[++n2].pre=tmp;
path2[n2].dir=i;
n1=vis1[v]-1;
return 1;
}
if(!vis2[v])
{
top.n=++n2;
path2[n2].pre=tmp;
path2[n2].dir=i;
vis2[v]=1+n2;
Q.push(top);
}
swap(tx, top.x), swap(ty, top.y);
swap(top.state[top.x][top.y],top.state[tx][ty]);
}
}
}
}
return 0;
}
int main()
{
init();
if(hash(end.state) == hash(pre.state));
else if(bfs())
{
int cnt=0,ans[1000];
while(n1>1)
{
ans[cnt++]=path1[n1].dir;
n1=path1[n1].pre;
}
for(int i=cnt-1;i>=0;i--) cout<<dir1[ans[i]];
while(n2>0)
{
cout<<dir2[path2[n2].dir];
n2=path2[n2].pre;
}
cout<<endl;
}
else cout << "unsolvable/n";
return 0;
}