#include<bits/stdc++.h>
#define Ll long long
using namespace std;
int fx[9]{0,1,1,1,2,3,3,3,2};
int fy[9]{0,1,2,3,3,3,2,1,1};
int xx[4]{1,-1,0,0};
int yy[4]{0,0,-1,1};
int a[4][4];
int n,m,x,y,z,X,Y,ans;
char c;
int h(){
int ans=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(a[i][j])ans+=abs(i-fx[a[i][j]])
+abs(j-fy[a[i][j]]);
return ans;
}
void dfs(int tf,int X,int Y,int g){
int H=h();
if(!H){ans=g;return;}
if(g==tf||ans||H+g>tf)return;
for(int i=0;i<4;i++){
int x=X+xx[i];
int y=Y+yy[i];
if(x&&y&&x<4&&y<4){
swap(a[X][Y],a[x][y]);
dfs(tf,x,y,g+1);
swap(a[X][Y],a[x][y]);
}
}
}
int main(){
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++){
cin>>c; a[i][j]=c-48;
if(!a[i][j])X=i,Y=j;
}
for(int tf=0;;tf++){
dfs(tf,X,Y,0);
if(ans){printf("%d",ans);return 0;};
}
}
IDA*-洛谷P1379 八数码难题
算法解释
一种剪枝方法,用于优化dfs,在进行dfs时,每次都预估一下至少还要几步才可以得到答案,若此时的深度加上估价已经大于当前的最小值,则直接剪枝
算法关键代码
int gj()
{
据题意而定;
}
void dfs(int now)
{
if(now+gj()>=mn) return;
}
模板题目描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
In
283104765
Out
4