1225 八数码难题
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
题目描述
Description
Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.
问题描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
输入描述
Input Description
输入初试状态,一行九个数字,空格用0表示
输出描述
Output Description
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
样例输入
Sample Input
283104765
样例输出
Sample Output
4
数据范围及提示
Data Size & Hint
详见试题
限定搜索的层数dfs
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 using namespace std; 5 using namespace std; 6 7 int mov1[4]={0,1,0,-1}; 8 int mov2[4]={1,0,-1,0}; 9 int st[4][4],ans,step; 10 bool flag=false; 11 int check() 12 { 13 if(st[1][1]!=1||st[1][2]!=2||st[1][3]!=3||st[2][1]!=8||st[2][2]!=0||st[2][3]!=4||st[3][1]!=7||st[3][2]!=6||st[3][3]!=5)return 0; 14 else return 1; 15 } 16 int jdg(int sx,int sy,int x,int y) 17 { 18 if(sx==x&&sy==y)return false; 19 if(sx<=3&&sy<=3&&sx>0&&sy>0)return true; 20 return false; 21 } 22 void search(int x,int y,int fx,int fy) 23 { 24 if(check()) 25 { 26 flag=true; 27 return ; 28 } 29 if(step==ans)return ; 30 for(int i=0; i<=3; i++) 31 { 32 int sx=x+mov1[i]; 33 int sy=y+mov2[i]; 34 if(jdg(sx,sy,fx,fy)) 35 { 36 swap(st[x][y],st[sx][sy]); 37 step++; 38 search(sx,sy,x,y); 39 step--; 40 swap(st[x][y],st[sx][sy]); 41 } 42 } 43 } 44 int main() 45 { 46 int si,sj; 47 for(int i=1; i<=3; i++) 48 for(int j=1; j<=3; j++) 49 { 50 scanf("%c",&st[i][j]); 51 st[i][j]-='0'; 52 if(st[i][j]==0)si=i,sj=j; 53 } 54 for(ans=0;;ans++) 55 { 56 search(si,sj,0,0); 57 if(flag) 58 { 59 cout<<ans; 60 return 0; 61 } 62 } 63 return 0; 64 }