题意:八数码
链接:点击打开链接
代码:
#include <map>
#include <set>
#include <queue>
#include <string>
#include <math.h>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
char s[50];
int xx[]={-1,0,1,0};
int yy[]={0,-1,0,1};
struct node{
int id,g,h;
string ss;
friend bool operator<(node a,node b){
return a.g+a.h>b.g+b.h;
}
};
node tmp;
int f[20],mp[500005],fa[500005],res[500005];
int KT(string s_tmp){
int i,j,u,v,siz;
siz=s_tmp.size();
for(i=0;i<siz;i++)
if(s_tmp[i]=='x')
s_tmp[i]='0';
v=0;
for(i=0;i<siz;i++){
u=0;
for(j=0;j<i;j++){
if(s_tmp[j]<s_tmp[i])
u++;
}
v+=(s_tmp[i]-'0'-u)*f[siz-i-1];
}
return v+1;
} //康拓展开,判断是全排列的第几位
int cal(string s){
int i,u,v,w,res=0;
for(i=0;i<s.size();i++){
u=i/3,v=i%3;
if(s[i]=='x')
res+=(abs(u-2)+abs(v-2));
else{
w=s[i]-'1';
res+=(abs(u-w/3)+abs(v-w%3));
}
}
return res;
} //用与初始位置的曼哈顿距离作为估价函数
int bfs(string s_st){
int i,u,v,tmp_x,tmp_y;
priority_queue<node> qu;
string s_tmp,s_end="12345678x";
memset(mp,0,sizeof(mp));
memset(fa,-1,sizeof(fa));
memset(res,-1,sizeof(res));
for(i=0;i<10;i++)
if(s_st[i]=='x')
u=i;
qu.push((node){u,1,cal(s_st),s_st});
mp[KT(s_st)]=1;
while(qu.size()){
tmp=qu.top();
if(tmp.ss==s_end)
return 1;
qu.pop();
u=tmp.id/3;
v=tmp.id%3;
for(i=0;i<4;i++){
tmp_x=u+xx[i];
tmp_y=v+yy[i];
if(tmp_x<0||tmp_x>2||tmp_y<0||tmp_y>2)
continue;
s_tmp=tmp.ss;
swap(s_tmp[tmp.id],s_tmp[tmp_x*3+tmp_y]);
if(mp[KT(s_tmp)]==1)
continue;
mp[KT(s_tmp)]=1;
fa[KT(s_tmp)]=KT(tmp.ss); //记录一下每个状态前一个状态和选择的方向
res[KT(s_tmp)]=i;
qu.push((node){tmp_x*3+tmp_y,tmp.g+1,cal(s_tmp),s_tmp});
}
}
return 0;
}
int main(){
int i,j,u,op;
string s_tmp;
vector<int> ans;
f[0]=1;
for(i=1;i<10;i++)
f[i]=f[i-1]*i;
while(gets(s)){
s_tmp="";
for(i=0;i<strlen(s);i++)
if(s[i]!=' ')
s_tmp+=s[i];
op=0;
for(i=0;i<s_tmp.size();i++){
if(s_tmp[i]!='x')
for(j=0;j<i;j++){
if(s_tmp[j]=='x')
continue;
if(s_tmp[j]>s_tmp[i])
op++;
}
}
if(op%2!=0){
puts("unsolvable");
continue;
}
if(bfs(s_tmp)){
ans.clear();
u=KT("12345678x");
while(u!=-1){
ans.push_back(res[u]);
u=fa[u];
}
for(i=ans.size()-1;i>=0;i--){
if(ans[i]==0)
printf("u");
if(ans[i]==1)
printf("l");
if(ans[i]==2)
printf("d");
if(ans[i]==3)
printf("r");
}
}
else
puts("unsolvable");
}
return 0;
}