题目描述 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
详见试题
!!!!!!!!:在对着别人的程序编就剁手!!!!!
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int c[9]={1,1,2,6,24,120,720,5040,40320}; 6 char mb[9]={1,2,3,8,0,4,7,6,5}; 7 int dict2[4]={0,0,1,-1}, 8 dict1[4]={-1,1,0,0}; 9 bool used[400000],sign; 10 int www; 11 int step[400000]; 12 char q[400000][9]; 13 int steps; 14 int hash(char str[9]) 15 { 16 int i,j,k; 17 int f[10]; 18 int sum=0; 19 memset(f,0,sizeof(f)); 20 for (i=0;i<9;i++) 21 { 22 k=0; 23 for (j=0;j<8;j++) 24 if (j<str[i] && !f[j]) 25 k++; 26 f[str[i]]=1; 27 sum+=k*c[8-i]; 28 } 29 return sum; 30 } 31 void bfs() 32 { 33 int i,j,h,t; 34 int x1,y1,z1,cx,cy,cz; 35 memset(used,0,sizeof(used)); 36 memset(step,0,sizeof(step)); 37 www=hash(q[0]); 38 used[www]=1; 39 h=0; 40 t=1; 41 while (h<t) 42 { 43 sign=0; 44 for (i=0;i<9;i++) 45 if (q[h][i]!=mb[i]) 46 { 47 sign=1; 48 break; 49 } 50 51 if (!sign) 52 { 53 steps=step[h]; 54 return; 55 } 56 57 for (i=0;i<9;i++) 58 if (q[h][i]==0) 59 { 60 x1=i/3; 61 y1=i%3; 62 z1=i; 63 break; 64 } 65 for (i=0;i<4;i++) 66 { 67 cx=x1+dict1[i]; 68 cy=y1+dict2[i]; 69 cz=cx*3+cy; 70 if ((cx>=0) && (cx<3) && (cy>=0) && (cy<3)) 71 { 72 for (j=0;j<9;j++) 73 q[t][j]=q[h][j]; 74 q[t][z1]=q[h][cz]; 75 q[t][cz]=0; 76 www=hash(q[t]); 77 if (!used[www]) 78 { 79 used[www]=1; 80 step[t]=step[h]+1; 81 t++; 82 } 83 } 84 } 85 h++; 86 } 87 steps=-1; 88 return; 89 } 90 int main() 91 { 92 int i; 93 char in[10]; 94 scanf("%s",in); 95 for (i=0;i<9;i++) 96 q[0][i]=in[i]-'1'+1; 97 bfs(); 98 printf("%d",steps); 99 return 0; 100 }