【A*/Meet in the middle/BFS模板】8数码问题
A*
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<stack>
using namespace std;
stack<char>s;
struct node{
int dist,h,c;
unsigned short s[10];
bool operator<(const node &tt)const
{
return h+dist>tt.h+tt.dist;
}
};
int stc,fact[10],f[362880+10],e,pre[362880+10];
unsigned short ppos[10][2]={{},{1,1},{1,2},{1,3},{2,1},{2,2},{2,3},{3,1},{3,2},{3,3}},st[10],goal[10]={0,1,2,3,4,5,6,7,8,0},dir[4][4]={{-1,0},{1,0},{0,-1},{0,1}};
unsigned short ffpos[4][4]={
{},
{0,1,2,3},
{0,4,5,6},
{0,7,8,9} };
char dd[4]={'u','d','l','r'},b[362880+10];
priority_queue<node>q;
int h(unsigned short *s){
int ret=0,i;
for(i=1;i<=9;i++){
if(!s[i])
continue;
ret+=abs(ppos[s[i]][0]-ppos[i][0])+abs(ppos[s[i]][1]-ppos[i][1]);
}
return ret;
}
bool vis[362880+10];
void init_lookup_table(){
fact[1]=1;
for(int i=2;i<=9;i++)
fact[i]=fact[i-1]*i;
}
int Cantor(unsigned short *s){
int code=0,i,j;
for(i=1;i<=9;i++){
int cnt=0;
for(j=i+1;j<=9;j++)
if(s[j]<s[i])
cnt++;
code+=fact[9-i]*cnt;
}
return code;
}
void structure(int c){
while(1){
if(c==stc)
break;
s.push(b[c]);
c=pre[c];
}
while(!s.empty()){
putchar(s.top());
s.pop();
}
}
void bfs(){
while(!q.empty()){
node p=q.top(),t;
q.pop();
if(p.c==e){
structure(e);
puts("");
return;
}
unsigned short x,y,z,d,tx,ty,tz;
for(z=1;z<=9;z++)
if(!p.s[z])
break;
x=ppos[z][0],y=ppos[z][1];
for(d=0;d<4;d++){
t=p;
t.dist++;
tx=x+dir[d][0],ty=y+dir[d][1],tz=ffpos[tx][ty];
if(!tx||!ty||tx>3||ty>3)
continue;
t.s[tz]=p.s[z];
t.s[z]=p.s[tz];
t.c=Cantor(t.s);
t.h=h(t.s);
if(!f[t.c]){
pre[t.c]=p.c;
b[t.c]=dd[d];
q.push(t);
f[t.c]=t.dist+t.h;
}
}
}
}
bool check(){
int ca=0,cb=0,i,j;
for(i=1;i<=9;i++)
for(j=i+1;j<=9;j++){
if(st[i]>st[j]&&st[j])
ca++;
if(goal[i]>goal[j]&&goal[j])
cb++;
}
if((ca&1)==(cb&1))
return 1;
return 0;
}
int main()
{
init_lookup_table();
while(1){
while(!q.empty())
q.pop();
memset(f,0,sizeof f);
int i;
char ch[10];
for(i=1;i<=9;i++){
if(scanf("%s",ch)==EOF)
return 0;
if(ch[0]=='x')
st[i]=0;
else
st[i]=ch[0]-'0';
}
if(!check()){
puts("unsolvable");
continue;
}
int c=Cantor(st);
stc=c;
e=Cantor(goal);
int hh=h(st);
f[c]=hh;
node t;
t.dist=0;
t.h=hh;
t.c=c;
memcpy(t.s,st,sizeof st);
q.push(t);
bfs();
}
}
Meet in the middle(不输出方案)
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int posx;
struct node
{
char s[10];
int hash;
int id;
int f;
node(const char *a,const int &b,const int &d,const int &e){
strcpy(s,a);
id=b;
f=d;
hash=e;
}
};
bool f[10],vis[2][370000];
int bv[10]={1,1,2,6,24,120,720,5040,40320},map[370000];
int order(char *t)
{
int ans=0;
for(int i=0;i<9;i++)
{
int tmp=0;
for(int j=i+1;j<9;j++)
{
if(t[i]>t[j])
tmp++;
}
ans+=tmp*bv[8-i];
}
return ans;
}
char a[10],b[10];
int dd[4]={-3,1,-1,3};
queue<node>q;
void BFS()
{
while(!q.empty())
{
int pos=q.front().id,k=q.front().f,hash=q.front().hash;
char*a=q.front().s;
for(int i=0;i<4;i++)
if(pos+dd[i]>=0&&pos+dd[i]<9&&(pos/3==(dd[i]+pos)/3||pos%3==(pos+dd[i])%3))
{
swap(a[pos],a[dd[i]+pos]);
int num=order(a);
if(!vis[k^1][num]&&!vis[k][num])
{
q.push(node(a,dd[i]+pos,k,num));
vis[k][num]=1;
map[num]=map[hash]+1;
}
else if(vis[k^1][num])
{
printf("%d\n",map[hash]+map[num]+1);
return;
}
swap(a[pos],a[dd[i]+pos]);
}
q.pop();
}
}
int main()
{
int t;
for(int i=0;i<9;i++)
{
scanf("%d",&t);
a[i]=t+'0';
if(!t)posx=i;
}
int num=order(a);
q.push(node(a,posx,0,num));
vis[0][num]=1;
for(int i=0;i<9;i++)
{
scanf("%d",&t);
b[i]=t+'0';
if(!t)posx=i;
}
num=order(b);
q.push(node(b,posx,1,num));
vis[1][num]=1;
int cnt1,cnt2;
cnt1=cnt2=0;
for(int i=1;i<9;++i)
for(int j=0;j<i;++j)
{
if(a[i]!='0'&&a[i]<a[j])cnt1++;
if(b[i]!='0'&&b[i]<b[j])cnt2++;
}
if((cnt1^cnt2)&1){printf("-1");return 0;}
BFS();
}
BFS
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<stack>
using namespace std;
stack<char>s;
struct node{
int dist,c;
int s[10];
};
int stc,fact[10],e,pre[362880+10];
int ppos[10][2]={{},{1,1},{1,2},{1,3},{2,1},{2,2},{2,3},{3,1},{3,2},{3,3}},st[10],goal[10]={0,1,2,3,4,5,6,7,8,0},dir[4][4]={{-1,0},{0,-1},{1,0},{0,1}};
int ffpos[4][4]={
{},
{0,1,2,3},
{0,4,5,6},
{0,7,8,9} };
char dd[4]={'u','l','d','r'},b[362880+10];
queue<node>q;
bool vis[362880+10];
void init_lookup_table(){
fact[1]=1;
for(int i=2;i<=9;i++)
fact[i]=fact[i-1]*i;
}
int Cantor(int *s){
int code=0,i,j;
for(i=1;i<=9;i++){
int cnt=0;
for(j=i+1;j<=9;j++)
if(s[j]<s[i])
cnt++;
code+=fact[9-i]*cnt;
}
return code;
}
void structure(int c){
while(1){
if(c==stc)
break;
s.push(b[c]);
c=pre[c];
}
while(!s.empty()){
putchar(s.top());
s.pop();
}
}
void bfs(){
while(!q.empty()){
node p=q.front(),t;
q.pop();
if(p.c==e){
structure(e);
puts("");
return;
}
int x,y,z,d,tx,ty,tz;
for(z=1;z<=9;z++)
if(!p.s[z])
break;
x=ppos[z][0],y=ppos[z][1];
for(d=0;d<4;d++){
t=p;
t.dist++;
tx=x+dir[d][0],ty=y+dir[d][1],tz=ffpos[tx][ty];
if(!tx||!ty||tx>3||ty>3)
continue;
t.s[tz]=p.s[z];
t.s[z]=p.s[tz];
t.c=Cantor(t.s);
if(!vis[t.c]){
pre[t.c]=p.c;
b[t.c]=dd[d];
q.push(t);
vis[t.c]=1;
}
}
}
}
bool check(){
int ca=0,cb=0,i,j;
for(i=1;i<=9;i++)
for(j=i+1;j<=9;j++){
if(st[i]>st[j]&&st[j])
ca++;
if(goal[i]>goal[j]&&goal[j])
cb++;
}
if((ca&1)==(cb&1))
return 1;
return 0;
}
int main()
{
init_lookup_table();
while(1){
while(!q.empty())
q.pop();
memset(vis,0,sizeof vis);
int i;
char ch[10];
for(i=1;i<=9;i++){
if(scanf("%s",ch)==EOF)
return 0;
if(ch[0]=='x')
st[i]=0;
else
st[i]=ch[0]-'0';
}
if(!check()){
puts("NO SOLUTION");
continue;
}
int c=Cantor(st);
stc=c;
e=Cantor(goal);
vis[c]=1;
node t;
t.dist=0;
t.c=c;
memcpy(t.s,st,sizeof st);
q.push(t);
bfs();
}
}