题目描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
输入输出格式
输入格式:输入初始状态,一行九个数字,空格用0表示
输出格式:
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
输入输出样例
输入样例#1:
283104765
输出样例#1:
4
思路:
一个很好的博客:
另一个:
#include#include #include #include using namespace std;int ans,num[4][4];int n,m,x,y,z,X,Y;int dx[4]={ 0,1,-1,0};int dy[4]={ 1,0,0,-1};int fx[11]={ 0,1,1,1,2,3,3,3,2};int fy[11]={ 0,1,2,3,3,3,2,1,1};int H(){ int bns=0; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) if(num[i][j]) bns+=abs(i-fx[num[i][j]])+abs(j-fy[num[i][j]]); return bns;}void dfs(int k,int X,int Y,int g){ int h=H(); if(!h){ ans=g; return ; } if(h+g>k||ans||g==k) return ; for(int i=0;i<4;i++){ int x=dx[i]+X; int y=dy[i]+Y; if(x>=1&&y>=1&&x<=3&&y<=3){ swap(num[X][Y],num[x][y]); dfs(k,x,y,g+1); swap(num[x][y],num[X][Y]); } }}int main(){ for(int i=1;i<=3;i++) for(int j=1;j<=3;j++){ char x; scanf("%c",&x); num[i][j]=x-'0'; if(!num[i][j]) X=i,Y=j; } for(int k=0;;k++){ dfs(k,X,Y,0); if(ans){ printf("%d",ans); return 0; } }}