很经典的八数码问题,可以用单向广度优先搜索、双向广度优先搜索、A*算法、IDA算法解。
用了双向广度优先搜索和A*算法解,在用A*算法时,纠结了好几天,后来在网上看了一份博客才发现自己错在哪。之后解出来了。虽然做这题时很纠结,不过收获真的很大,痛而快乐着…………
下面贴出用双向广度优先搜索和A*算法做的代码
//A*算法
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int maxn=362882;
int n1,n2; //n1记录正向搜索的步骤数,n2记录逆向搜索的步骤数
int num[10];
int visit1[maxn],visit2[maxn]; //正向搜索的访问数组,逆向搜索的访问数组
int dir[4][2]={
{1,0},{-1,0},{0,-1},{0,1}};
char dir1[4]={'d','u','l','r'};
char dir2[4]={'u','d','r','l'};
struct node //棋盘状态结点
{
int x;
int y;
int step; //到达该状态走了多少步
char map[3][3];
}s,e;
struct path //路径
{
int dir; //到该步的方向
int pre; //该步的前一步
}path1[maxn],path2[maxn]; //正向搜索路径,逆向搜索路径
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
bool check(int x,int y)
{
if(x>=0 && x<3 && y>=0 &&y<3)
return true;
else
return false;
}
void Init()
{
int i,j;
char ch;
n1=0;
n2=0;
num[0]=1;
for(i=1;i<=9;i++)
num[i]=num[i-1]*i;
e.x=2; //最终状态的坐标值
e.y=2;
for(i=0;i<3;i++) //初始化棋盘上的各个格子的值
for(j=0;j<3;j++)
e.map[i][j]=i*3+j+1+'0';
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
cin>>ch;
if(ch=='x')
{
s.map[i][j]='9';
s.x=i;
s.y=j;
}
else
s.map[i][j]=ch;
}
}
int calculate(char m[][3]) //计算所处的状态
{
int i,j,a,b,v,count,temp;
v=0;
for(i=0;i<9;i++)
{
count=0;
a=m[i/3][i%3]-48;
for(j=i+1;j<9;j++)
{
b=m[j/3][j%3]-48;
if(a>b)
count++;