第一次写双向宽搜,比单向快很多。
要点:在判重的时候要注意对方是否已经到达。
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<math.h>
#include<stdlib.h>
#define M 400000
using namespace std;
struct stu
{
char s[20];
int pos;
}st,ed,cdl[M],zdl[M];
struct pa
{
int fa;
char c;
}cpath[M],zpath[M];
int cmark[M],zmark[M];
int jc[12];
int h[4]={-1,0,1,0};
int z[4]={0,1,0,-1};
char fa[4][2]={'u','d','r','l','d','u','l','r'},pstr[M];
void getjc()//阶乘
{
int i,j,k;
jc[0]=1;
for(i=1;i<12;i++)
jc[i]=jc[i-1]*i;
}
int getkt(char s[20])//康托展开
{
int i,j,k,len,an[20],ans=0;
len=strlen(s);
memset(an,0,sizeof(an));
for(i=0;i<len;i++)//获得当前未出现的比他小的数,即它右边有几个比他小的数
for(j=0;j<i;j++)
{
if(s[j]>s[i])
an[j]++;
}
for(i=0;i<len;i++)//康托公式运算
{
ans+=an[i]*jc[len-i-1];
}
return ans;
}
int judge(int x,int y)
{
return (x>=0&&x<3&&y>=0&&y<3);
}
void getpath(int kt)
{
int i=0,zd,bg;
bg=kt;
zd=getkt(st.s);
while(bg!=zd)
{
pstr[i++]=cpath[bg].c;
bg=cpath[bg].fa;
}
pstr[i]='\0';
reverse(pstr,pstr+i);
printf("%s",pstr);
// printf("\nc->z\n");
bg=kt;
zd=getkt(ed.s);
while(bg!=zd)
{
printf("%c",zpath[bg].c);
bg=zpath[bg].fa;
}
puts("");
}
int bbfs()
{
int i,j,k;
int cf,cr,zf,zr,x,y,t;
cf=cr=zf=zr=0;
char c;
memset(cmark,0,sizeof(cmark));
memset(zmark,0,sizeof(zmark));
zdl[0]=ed;
cdl[0]=st;
k=getkt(ed.s);
zmark[k]=1;
k=getkt(st.s);
cmark[k]=1;
while(cr<=cf&&zr<=zf)
{
k=cf;
for(cr;cr<=k;cr++)
{
int kt=getkt(cdl[cr].s);
if(zmark[kt]==1)
{
return kt;
}
for(i=0;i<4;i++)
{
stu nw;
strcpy(nw.s,cdl[cr].s);
int p=cdl[cr].pos;
x=p/3;
y=p%3;
x+=h[i];
y+=z[i];
if(judge(x,y))
{
t=x*3+y;
c=nw.s[p];
nw.s[p]=nw.s[t];
nw.s[t]=c;
nw.pos=t;
t=getkt(nw.s);
if(cmark[t]==0)
{
cdl[++cf]=nw;
cpath[t].fa=kt;
cpath[t].c=fa[i][0];
cmark[t]=1;
}
}
}
}
k=zf;
for(zr;zr<=k;zr++)
{
int kt=getkt(zdl[zr].s);
if(cmark[kt]==1)
{
return kt;
}
for(i=0;i<4;i++)
{
stu nw;
strcpy(nw.s,zdl[zr].s);
int p=zdl[zr].pos;
x=p/3;
y=p%3;
x+=h[i];
y+=z[i];
if(judge(x,y))
{
t=x*3+y;
c=nw.s[p];
nw.s[p]=nw.s[t];
nw.s[t]=c;
nw.pos=t;
t=getkt(nw.s);
if(zmark[t]==0)
{
zdl[++zf]=nw;
zpath[t].fa=kt;
zpath[t].c=fa[i][1];
zmark[t]=1;
}
}
}
}
}
return -1;
}
int main()
{
getjc();
int i,j,k;
char c;
for(i=0;i<9; )
{
scanf("%c",&c);
if(c == 'x')
{
st.s[i]='0';
st.pos=i;
i++;
}
else if(c>='0'&&c<='9')
{
st.s[i] = c;
i++;
}
else
continue;
}
st.s[9]='\0';
strcpy(ed.s,"123456780");
ed.pos=8;
int ans=bbfs();
if(ans==-1)
{
puts("unsolvable");
}
else
{
getpath(ans);
}
return 0;
}