八数码问题
描述:
在九宫格里放在1到8共8个数字还有一个是空格,与空格相邻的数字可以移动到空格的位置,问给定的状态最少需要几步能到达目标状态(用0表示空格):
1
2 3
4 5 6
7 8 0
输入:
输入一个给定的状态。
输出:
输出到达目标状态的最小步数。不能到达时输出-1。
输入样例:
1 2 3
4 0 6
7 5 8
输出样例:
2
思路:
广搜的经典题。
1 #include<cstdio> 2 #include<map> 3 #include<cstring> 4 #include<algorithm> 5 6 using namespace std; 7 8 map <int,bool> res; 9 10 int a[10][10],ans,que[500000][2],st,ed,flg=54480996; 11 int zerox,zeroy,dirx[5]={0,-1,0,1,0},diry[5]={0,0,1,0,-1}; 12 13 void input() 14 { 15 for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)scanf("%d",&a[i][j]); 16 return ; 17 } 18 19 int gethash() 20 { 21 int ret=0; 22 for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)ret=ret*9+a[i][j]; 23 return ret; 24 } 25 26 void poszero() 27 { 28 for(int i=1;i<=3;i++)for(int j=1;j<=3;j++) 29 { 30 if(a[i][j]==0) 31 { 32 zerox=i; 33 zeroy=j; 34 break; 35 } 36 } 37 return ; 38 } 39 40 void update(int has) 41 { 42 for(int i=3;i>=1;i--)for(int j=3;j>=1;j--) 43 { 44 a[i][j]=has%9; 45 has/=9; 46 } 47 } 48 49 int main() 50 { 51 input(); 52 int dang=gethash(); 53 if(dang==flg) 54 { 55 printf("0\n"); 56 return 0; 57 } 58 res[dang]=true; 59 st++; 60 que[st][0]=dang; 61 que[st][1]=0; 62 while(st!=ed) 63 { 64 ed++; 65 int now=que[ed][0]; 66 update(now); 67 poszero(); 68 for(int i=1;i<=4;i++) 69 { 70 swap(a[zerox][zeroy],a[zerox+dirx[i]][zeroy+diry[i]]); 71 int tem=gethash(); 72 if(tem==flg) 73 { 74 printf("%d\n",que[ed][1]+1); 75 return 0; 76 } 77 if(!res[tem]) 78 { 79 st++; 80 que[st][0]=tem; 81 que[st][1]=que[ed][1]+1; 82 res[tem]=true; 83 } 84 swap(a[zerox][zeroy],a[zerox+dirx[i]][zeroy+diry[i]]); 85 } 86 } 87 printf("-1\n"); 88 return 0; 89 }