为什么就是跑不出0ms
八数码0.0,我又来水博客了。
IDA*算法,A*为曼哈顿距离,判重用康拓展开。
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int a[4][4];
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
char s[]="123804765";
int end[4][4];
int x,y;
int dep;
bool vis[400000];
int ca[]={1,1,2,6,24,120,720,5040,40320,362880};
inline int cantor()
{
int sum=0;
for(int i=0;i<9;i++)
{
int num=0;
for(int j=i+1;j<9;j++)
if(a[i/3][i%3]<a[j/3][j%3]) num++;
sum+=(num*ca[9-i-1]);
}
return sum+1;
}
struct node
{
int x,y;
}p[12];
inline bool ok() //判断是否结束
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(p[a[i][j]].x!=i||p[a[i][j]].y!=j) return false;
}
}
return true;
}
inline int dist(int x1,int y1,int x2,int y2)//求两点的曼哈顿距离
{
return abs(x1-x2)+abs(y1-y2);
}
int h() //求估价值
{
int l=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(a[i][j]==0) continue;
l+=dist(i,j,p[a[i][j]].x,p[a[i][j]].y);
}
}
return l;
}
bool dfs(int now,int x,int y) //(x,y)保存0的位置
{
if(ok()) return true;
if(now+h()>dep) return false;
for(int d=0;d<4;d++)
{
int nx=x+dx[d];
int ny=y+dy[d];
if(nx>=0&&nx<3&&ny>=0&&ny<3)
{
int can=cantor();
if(vis[can]) continue;
vis[can]=true;
swap(a[nx][ny],a[x][y]);
if(dfs(now+1,nx,ny)) return true;
swap(a[nx][ny],a[x][y]);
vis[can]=false;
}
}
return false;
}
char str[12];
int main()
{
scanf("%s",str);
for(int i=0,b=0;i<3;i++)
{
for(int j=0;j<3;b++,j++)
{
p[s[b]-'0'].x=i; //记录目标数字对应的位置
p[s[b]-'0'].y=j;
a[i][j]=str[b]-'0';
if(!a[i][j])
{
x=i;
y=j;
}
}
}
cantor();
for(dep=h();;dep++) //迭代加深搜索
{
if(dfs(0,x,y)) break;
}
printf("%d\n",dep);
return 0;
}