广搜+预处理 265MS 19436K
内存用的很大
#include<iostream>
#include<queue>
using namespace std;
const int MAX=362890;
struct eight
{
int map[9];
int zero;
int id;
// string route;
}now,next;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char dir[4]={'u','d','l','r'};
int key[9]={1,1,2,6,24,120,720,5040,40320};
bool hash[MAX];
string route[MAX];
int num_to_hash(int *);
int bfs();
void show(int k);
int end;
int main()
{
char c;
int start[9];
int temp;
bfs();
while(cin>>c)
{
int k=0;
int i=0;
c=='x'?start[i]=0:start[i]=c-'0';
for(i=1;i<9;i++)
cin>>c,c=='x'?start[i]=0:start[i]=c-'0';
temp=0;
for(i=0;i<9;i++)
{
for(int j=i+1;j<9;j++)
{
if(start[i]>start[j])
temp++;
}
}
end=num_to_hash(start);
show(end);
}
return 0;
}
int num_to_hash(int *t)
{
int sum=0,temp;
for(int i=0;i<9;i++)
{
temp=0;
for(int j=i+1;j<9;j++)
{
if(t[i]>t[j])
temp++;
}
sum+=temp*key[8-i];
}
return sum;
}
int bfs()
{
queue<eight>q;
int x,y,nx,ny;
memset(hash,false,sizeof(hash));
int temp;
now.zero=8;
for(int i=1;i<9;i++)
now.map[i-1]=i;
now.map[8]=0;
now.id=num_to_hash(now.map);
route[now.id]="";
q.push(now);
hash[now.id]=true;
while(!q.empty())
{
now=q.front();
q.pop();
x=now.zero/3;
y=now.zero%3;
for(int i=0;i<4;i++)
{
nx=x+d[i][0];
ny=y+d[i][1];
if(nx<0 || nx>2 || ny<0 || ny>2)
continue;
next=now;
temp=nx*3+ny;
next.map[now.zero]=next.map[temp];
next.map[temp]=0;
next.zero=temp;
temp=num_to_hash(next.map);
next.id=temp;
if(!hash[temp])
{
hash[temp]=true;
route[temp]=route[now.id];
route[temp]+=dir[i];
q.push(next);
}
}
}
return 0;
}
void show(int t)
{
if(!hash[t])
cout<<"unsolvable";
else
for(int k=route[t].size()-1;k>=0;k--)
cout<<route[t][k];
cout<<endl;
}
A* +曼哈顿距离 625MS 752K
不用预处理625MS, 重点是752K内存,比广搜的零头还少
#include<iostream>
#include<queue>
using namespace std;
const int MAX=362890;
struct eight
{
int map[9];
int zero;
int id;
int realstep;
int manhattan;
bool operator < (const eight & e)const
{
int a,b;
a=15*manhattan+realstep;
b=15*e.manhattan+e.realstep;
if(a!=b)
return a>b;
else
return realstep>e.realstep;
}
string route;
}now,next;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char dir[4]={'d','u','r','l'};
int key[9]={1,1,2,6,24,120,720,5040,40320};
bool hash[MAX];
int num_to_hash(int *);
int Manhattan(int *);
void show();
void bfs();
inline abs(int a);
string answer;
int main()
{
char c;
while(cin>>c)
{
int k=0;
int i=0;
c=='x'? (now.map[i]=0,now.zero=i) : now.map[i]=c-'0';
for(i=1;i<9;i++)
cin>>c,c=='x'? (now.map[i]=0,now.zero=i) : now.map[i]=c-'0';
int temp=0;
for(i=0;i<9;i++)
{
for(int j=i+1;j<9;j++)
{
if(now.map[i]>now.map[j] && now.map[i]!=0 && now.map[j]!=0)
temp++;
}
} //逆序数对
if(temp%2==1)
cout<<"unsolvable"<<endl;
else
{
now.id=num_to_hash(now.map);
if(now.id==46233)
cout<<endl;
else
{
bfs();
show();
}
}
}
return 0;
}
int num_to_hash(int *t)
{
int sum=0,temp;
for(int i=0;i<9;i++)
{
temp=0;
for(int j=i+1;j<9;j++)
{
if(t[i]>t[j])
temp++;
}
sum+=temp*key[8-i];
}
return sum;
}
int Manhattan(int * t)
{
int sum=0;
for(int i=0;i<9;i++)
{
if(t[i]!=0)
{
sum+= abs((t[i]-1)/3-i/3) + abs((t[i]-1)%3-i%3);
}
}
return sum;
}
void bfs()
{
priority_queue<eight>q;
int x,y,nx,ny;
memset(hash,false,sizeof(hash));
answer="";
int temp;
now.manhattan=Manhattan(now.map);
now.realstep=0;
now.route="";
q.push(now);
hash[now.id]=true;
while(!q.empty())
{
now=q.top();
q.pop();
x=now.zero/3;
y=now.zero%3;
for(int i=0;i<4;i++)
{
nx=x+d[i][0];
ny=y+d[i][1];
if(nx<0 || nx>2 || ny<0 || ny>2)
continue;
next=now;
temp=nx*3+ny;
next.map[now.zero]=next.map[temp];
next.map[temp]=0;
next.zero=temp;
next.realstep++;
// if(next.realstep>50)
// continue;
temp=num_to_hash(next.map);
if(!hash[temp])
{
next.manhattan=Manhattan(next.map);
next.route+=dir[i];
next.id=temp;
hash[temp]=true;
if(temp==46233)
{
answer=next.route;
return ;
}
q.push(next);
}
}
}
}
void show()
{
if(!hash[46233])
cout<<"unsolvable";
else
for(int k=0;k<answer.size();k++)
cout<<answer[k];
cout<<endl;
}
inline abs(int a)
{
return a>0? a:-a;
}