版权声明:沃斯里德小浩浩啊 https://blog.csdn.net/Healer66/article/details/83574651
单向BFS
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,char> pic;
struct Node
{
int s[9];//当前排列
int ri,ci;//x的位置
int status;//状态的康拓映射
int cnt;//移动步数
Node()
{
memset(s,0,sizeof(s));
ri=ci=0;
status=-1;
cnt=0;
}
};
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};//
char in[20];
Node st,ed;
queue<Node> Q;
int fac[9];
bool vis[(int)4e5+10];
map<int,pair<int,int> >pre;//记录路径
bool InMap(int ri,int ci)
{
return ri>=0&&ri<3&&ci>=0&&ci<3;
}
int Cantor(int s[])//康拓展开求排列序号
{
int ret=0;
for(int i=0; i<9; i++)
{
int cnt=0;
for(int j=i+1; j<9; j++)
{
if(s[j]<s[i])cnt++;
}
ret+=cnt*fac[8-i];
}
return ret;
}
int BFS(const Node& st,int edval)
{
memset(vis,false,sizeof(vis));
while(!Q.empty())Q.pop();
pre.clear();
Q.push(st);
vis[st.status]=true;
pre[st.status]=make_pair(-1,-1);
while(!Q.empty())
{
Node u=Q.front();
Q.pop();
if(u.status==edval)return u.cnt;
for(int di=0; di<4; di++)
{
Node v=u;
v.ri=u.ri+dir[di][0];
v.ci=u.ci+dir[di][1];
if(!InMap(v.ri,v.ci))continue;
int upos=3*u.ri+u.ci;
int vpos=3*v.ri+v.ci;
swap(v.s[upos],v.s[vpos]);
v.status=Cantor(v.s);
if(vis[v.status])continue;
vis[v.status]=true;
v.cnt=u.cnt+1;
Q.push(v);
pre[v.status]=make_pair(u.status,di);
if(v.status==edval)return v.cnt;
}
}
return -1;
}
int main()
{
fac[0]=1;
for(int i=1; i<9; i++)fac[i]=i*fac[i-1];
ed.ri=ed.ci=2;
for(int i=0; i<9; i++)
{
ed.s[i]=i+1;
}
ed.status=Cantor(ed.s);
while(cin>>in[0])
{
for(int i=1; i<9; i++)cin>>in[i];
for(int ri=0; ri<9; ri++)
{
if('x'==in[ri])
{
st.s[ri]=9;
st.ri=ri/3;
st.ci=ri%3;
}
else st.s[ri]=in[ri]-'0';
}
st.status=Cantor(st.s);
st.cnt=0;
int flag=BFS(st,ed.status);
if(-1==flag)puts("unsolvable");
else
{
char ans[1000];
char ch[5]="udlr";//与dir方向对应
int k=ed.status;
ans[flag]=0;
while(k!=st.status)
{
flag--;
ans[flag]=ch[pre[k].second];
k=pre[k].first;
}
puts(ans);
}
}
return 0;
}
双向BFS
http://www.cnblogs.com/bofengyu/p/4825529.html
#include <bits/stdc++.h>
using namespace std;
const int maxn = 362885; //状态数9!
int dir[4] = {-3,3,-1,1}; //某个方向移动对应一维的位置变化
char opf[4] = {'u','d','l','r'};//正向bfs对应的
char opr[4] = {'d','u','r','l'};
int fac[9] = {1,1,2,6,24,120,720,5040,40320};//康拓展开
bool visf[maxn];//标记正向状态是否访问
bool visr[maxn];
string targs = "123456789";//目标状态
struct Node
{
string s;
int xloca;
} node;
struct Node2
{
int idf,idr;//正向前驱和后驱
char cf,cr;//对应的操作
} op[maxn];
int cantor(string s)//求排列对应的康拓展开
{
int num = 0;
for(int i = 0; i < 9; i++)
{
int t = 0;
for(int j = i + 1; j < 9; j++)
{
if(s[j] < s[i])
t++;
}
num += fac[8-i] * t;
}
return num;
}
void print(int i)//递归输出
{
if(op[i].idf == -1) return;
print(op[i].idf);
cout<<op[i].cf;
}
void DoubleBFS()
{
queue<Node> qf,qr;
Node t1,t2;
int hash1,hash2,xloca;
t1 = node; //初始状态
t2.s = targs;//目标状态.
t2.xloca = 8;//目标状态x位置
hash1 = cantor(t1.s);
visf[hash1] = true;
op[hash1].idf = -1;
qf.push(t1);
hash1 = cantor(t2.s);
visr[hash1] = true;
op[hash1].idr = -1;
qr.push(t2);
while(!qf.empty()&&!qr.empty())
{
//正向bfs
t1 = qf.front();
qf.pop();
hash1 = cantor(t1.s);
if(visr[hash1])
{
print(hash1);
hash2 = hash1;
while(op[hash2].idr != -1)
{
cout<<op[hash2].cr;
hash2 = op[hash2].idr;
}
cout<<endl;
return ;
}
for(int i = 0; i < 4; i++)
{
if(i == 0 && t1.xloca < 3) continue;
if(i == 1 && t1.xloca > 5) continue;
if(i == 2 && t1.xloca%3 == 0) continue;
if(i == 3 && t1.xloca%3 == 2) continue;
xloca = t1.xloca + dir[i];
t2 = t1;
swap(t2.s[t1.xloca],t2.s[xloca]);
hash2 = cantor(t2.s);
if(!visf[hash2])
{
visf[hash2] = true;
t2.xloca = xloca;
op[hash2].idf = hash1;
op[hash2].cf = opf[i];
qf.push(t2);
}
}
//反向bfs
t1 = qr.front();
qr.pop();
hash1 = cantor(t1.s);
if(visf[hash1])
{
print(hash1);
hash2 = hash1;
while(op[hash2].idr != -1)
{
cout<<op[hash2].cr;
hash2 = op[hash2].idr;
}
cout<<endl;
return;
}
for(int i = 0; i < 4; i++)
{
if(i == 0 && t1.xloca < 3) continue;
if(i == 1 && t1.xloca > 5) continue;
if(i == 2 && t1.xloca%3 == 0) continue;
if(i == 3 && t1.xloca%3 == 2) continue;
xloca = t1.xloca + dir[i];
t2 = t1;
swap(t2.s[t1.xloca],t2.s[xloca]);
hash2 = cantor(t2.s);
if(!visr[hash2])
{
visr[hash2] = true;
t2.xloca = xloca;
op[hash2].idr = hash1;
op[hash2].cr = opr[i];
qr.push(t2);
}
}
}
}
int main()
{
string str;
int len;
int ivsNum;//逆序数
while(getline(cin,str))
{
memset(visf,0,sizeof visf);
memset(visr,0,sizeof visr);
len = str.size();
node.s = "";
int k = 0;
for(int i = 0; i < len; i++)
{
if(str[i]!=' ')
{
if(str[i] == 'x')
{
node.s = node.s + '9';
node.xloca = k;
}
else
{
node.s = node.s + str[i];
}
k++;
}
}
//cout<<node.s<<endl;
ivsNum = 0;
for(int i = 0; i < 9; i++)
{
if(node.s[i] == '9') continue;
for(int j =0; j < i; j++)
{
if(node.s[j] == '9') continue;
if(node.s[j] > node.s[i])
ivsNum ++;
}
}
if(ivsNum & 1)
cout<<"unsolvable"<<endl;
else
DoubleBFS();
}
return 0;
}
逆向BFS+离线打表//不完备
#include <bits/stdc++.h>
using namespace std;
const int N = 512345;
char ss[10];
struct node
{
char str[10];
vector<int> res;
int index,num;
};
vector<int> res[N];
bool vis[N];
int fac[] = {1,1,2,6,24,120,720,5040,40320};
int over;
int ans[N];
int contor(char ss[])
{
int t,sum;
int s[10];
for(int i = 0; i < 9; i++)
{
if(ss[i]=='x')
s[i] = 0;
else
s[i]=ss[i]-'0';
}
sum = 0;
for(int i = 0; i < 9;i++)
{
t = 0;
for(int j = i + 1; j < 9; j++)
{
if(s[j] < s[i])
t++;
}
sum += t *fac[9-i-1];
}
return sum+1;
}
void bfs()
{
char c;
queue<node> q;
over = contor(ss);
node g,h;
for(int i = 0; i < 8;i++)
{
g.str[i] = i + 1 + '0';
}
g.str[8] = 'x';
g.str[9] = '\0';
g.res.clear();g.index = 8;g.num = 0;
int t = contor(g.str);
vis[t] = true;
q.push(g);
while(!q.empty())
{
g = q.front(); q.pop();
int t = contor(g.str);
res[t] = g.res;
g.num ++;
h = g;
if((h.index+1)%3 != 0)
{
swap(h.str[h.index],h.str[h.index+1]);
h.index ++;
h.res.push_back(4);
int t = contor(h.str);
if(!vis[t])
{
vis[t] = true;
q.push(h);
}
}
h = g;
if(h.index%3 != 0)
{
swap(h.str[h.index],h.str[h.index-1]);
h.index--;
h.res.push_back(3);
int t= contor(h.str);
if(!vis[t])
{
vis[t] = true;
q.push(h);
}
}
h = g;
if(h.index < 6)
{
swap(h.str[h.index],h.str[h.index+3]);
h.index += 3;
h.res.push_back(2);
int t = contor(h.str);
if(!vis[t])
{
vis[t] = 1;
q.push(h);
}
}
if(h.index > 2)
{
swap(h.str[h.index],h.str[h.index-3]);
h.index -= 3;
h.res.push_back(1);
int t = contor(h.str);
if(!vis[t])
{
vis[t] = 1;
q.push(h);
}
}
}
}
int main()
{
int k,t,x,y,z;
for(int i = 0; i < N; i++) res[i].clear();
bfs();
while(scanf("%s",ss)!=EOF)
{
memset(vis,false,sizeof vis);
for(int i = 1; i < 9; i++)
scanf("%s",ss+i);
//cout<<ss<<endl;
t = contor(ss);
// for(int i = 1; i<= 46234;i++ )
// cout<<res[i].size()<<endl;
if(res[t].size()!=0 || t == 46234)
{
for(int i = res[t].size() - 1; i >= 0; i--)
{
if(res[t][i] == 1) cout<<"d";
else if(res[t][i] == 2) cout<<"u";
else if(res[t][i] == 3) cout<<"r";
else if(res[t][i] == 4) cout<<"l";
}
}
else
cout<<"unsolvable";
cout<<endl;
}
}