目录
POJ1077Eight
1.直接广搜,超时
//POJ1077直接广搜超时。。。
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
#define N 3
#define N2 9
struct Puzzle{
int f[N2]; //当前状态的数组
int space; //八数码中空格所对应的f[i]中的下标i
string path;
bool operator < (const Puzzle &p) const {
for(int i=0;i<N2;i++){
if(f[i]==p.f[i]) continue;
return f[i]>p.f[i];
}
return false;
}
};
static const int dx[4]={-1,0,1,0};
static const int dy[4]={0,-1,0,1};
static const char dir[4]={'u','l','d','r'};
bool isTarget(Puzzle p){ //判断当前状态是不是目标状态
for(int i=0;i<N2;i++)
if(p.f[i]!=(i+1)) return false;
return true;
}
string bfs(Puzzle s){
queue<Puzzle> Q;
map<Puzzle,bool> V; //标记状态,初始时,全部默认为false
Puzzle u,v;
s.path="";
Q.push(s);
V[s]=true;
while(!Q.empty()){
u=Q.front(); Q.pop();
//cout<<"u.path="<<u.path<<endl;
if(isTarget(u)) return u.path;
int sx=u.space/N; //空格的坐标
int sy=u.space%N;
for(int r=0;r<4;r++){
int tx=sx+dx[r];
int ty=sy+dy[r];
if(tx<0||ty<0||tx>=N||ty>=N) continue;
v=u;
swap(v.f[u.space],v.f[tx*N+ty]); //换格子
v.space=tx*N+ty; //记录当前状态下空格的位置
if(!V[v]){ //如果当前状态没有访问过,将当前状态压入队列中
V[v]=true;
v.path+=dir[r]; //存储路径,直接字符串连接+即可
Q.push(v);
}
}
}
return "unsolvable";
}
int main(){
Puzzle in;
char ch;
for(int i=0;i<N2;i++){
cin>>ch;
if(ch=='x'){
in.f[i]=N2; //set space
in.space=i;
}else in.f[i]=ch-'0';
//cout<<"***="<<in.f[i]<<endl;
}
string ans=bfs(in);
cout<<ans<<endl;
return 0;
}
2.用A*实现搜索——AC
//A*
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
#define N 3
#define N2 9
static const int dx[4]={-1,0,1,0};
static const int dy[4]={0,-1,0,1};
static const char dir[4]={'u','l','d','r'};
int MDT[N2][N2];
struct Puzzle{
int f[N2];
int space; //八数码中空格所对应的f[i]中的下标i
int MD,cost;
int pre;
string path;
bool operator < (const Puzzle &p) const {
for(int i=0;i<N2;i++){
if(f[i]==p.f[i]) continue;
return f[i]<p.f[i];
}
return false;
}
};
struct State{
Puzzle puzzle;
int estimated;
bool operator < (const State &s)const{
return estimated>s.estimated; //在优先队列中,曼哈顿距离越小,优先级越高
}
};
int getAllMD(Puzzle pz){
int sum=0;
for(int i=0;i<N2;i++){
if(pz.f[i]==N2) continue;
sum+=MDT[i][pz.f[i]-1];
}
return sum;
}
string astar(Puzzle s){
priority_queue<State> PQ;
s.MD=getAllMD(s);
s.cost=0;
s.path="";
s.pre=-1;
map<Puzzle,bool> V; //标记状态,初始时,全部默认为false
Puzzle u,v;
State initial;
initial.puzzle=s;
initial.estimated=getAllMD(s);
PQ.push(initial);
while(!PQ.empty()){
State st=PQ.top(); PQ.pop();
u=st.puzzle;
if(u.pre!=-1) u.path+=dir[u.pre];
if(u.MD==0) return u.path;
V[u]=true;
int sx=u.space/N; //空格的坐标
int sy=u.space%N;
for(int r=0;r<4;r++){
int tx=sx+dx[r];
int ty=sy+dy[r];
if(tx<0||ty<0||tx>=N||ty>=N) continue;
v=u;
v.MD-=MDT[tx*N+ty][v.f[tx*N+ty]-1];
v.MD+=MDT[sx*N+sy][v.f[tx*N+ty]-1];
swap(v.f[sx*N+sy],v.f[tx*N+ty]); //换格子
v.space=tx*N+ty; //记录当前状态下空格的位置
if(!V[v]){
v.cost++;
v.pre=r;
State news;
news.puzzle=v;
news.estimated=v.cost+v.MD;
PQ.push(news);
}
}
}
return "unsolvable";
}
int main(){
for(int i=0;i<N2;i++)
for(int j=0;j<N2;j++)
MDT[i][j]=abs(i/N-j/N)+abs(i%N-j%N);
Puzzle in;
char ch;
for(int i=0;i<N2;i++){
cin>>ch;
if(ch=='x'){
in.f[i]=N2; //set space
in.space=i;
}else in.f[i]=ch-'0';
//cout<<"***="<<in.f[i]<<endl;
}
cout<<astar(in)<<endl;
return 0;
}