8数码

来源:互联网 发布:php网站打开一片空白 编辑:程序博客网 时间:2024/04/29 06:54
Description
传统的我们有8数码问题,即在一个3×3的矩阵中有8个数(1至8)和一个空格,问题要你从一个状态转换到另一个状态,每次只能移动与空格相邻的一个数字到空格当中。
现在给你两个个3*3的矩阵,请给出两个矩阵相互转化的最少步数。

Input
第1行-第3行:3个空格分隔的整数,代表初始状态相应位置的数字,0代表空格
第4行-第6行:3个空格分隔的整数,代表终止状态相应位置的数字,0代表空格

Output
第1行:一个整数,最小转换步数,如不能到相互转化则输出"Impossible"

Sample Input
OriginalTransformed
1 2 38 0 47 6 51 2 37 8 40 6 5

Sample Output
OriginalTransformed
2


代码如下:
#include "stdafx.h"#include <stdio.h>#include <string.h>#include <stdlib.h>char a[363000][9];   // 共有9!=362880种情况,用char存储节省空间。char goal[9];char visit[363000];int dis[363000];int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};int c[9]={1,1,2,6,24,120,720,5040,40320};// 将字符串转换成一个整数int find(char str[9]){int i,j,k;int f[10];int sum = 0;memset(f,0,sizeof(f));for(i=0;i<9;i++){k=0;for(j=0;j<8;j++)if(j<str[i]&&f[j])k++;f[str[i]] = 1;sum += k*c[8-i];}return sum;}int bfs(){int i,j,t,flag;int head,tail;int x,y,z;int nx,ny,nz;  memset(dis,0,sizeof(dis));  //到每种状态的做小步数      memset(visit,0,sizeof(visit)); //标记过的点不能重复走      t=find(a[0]);      visit[t]=1;      head=0;      tail=1;      while(head<tail)      {          flag=1;          for(i=0;i<9;i++)          if(a[head][i]!=goal[i])   //和目标状态相同即停止搜索          {              flag=0;              break;          }          if(flag)          return dis[head];          for(i=0;i<9;i++)  //找到0所在位置          if(a[head][i]==0)          {              x=i/3;              y=i%3;              z=i;              break;          }          for(i=0;i<4;i++)          {              nx=x+dir[i][0];              ny=y+dir[i][1];              nz=nx*3+ny;              if(0<=nx&&nx<3&&0<=ny&&ny<3)              {                  for(j=0;j<9;j++)                  a[tail][j]=a[head][j];                  a[tail][z]=a[head][nz];  //做一次移动,即非0元素和0交换                  a[tail][nz]=0;                  t=find(a[tail]);                  if(!visit[t])                  {                      visit[t]=1;                      dis[tail]=dis[head]+1;                      tail++;                  }              }          }          head++;      }      return -1;}int _tmain(int argc, _TCHAR* argv[]){int i,ans;for(i=0;i<9;i++)scanf("%d",&a[0][i]);for(i=0;i<9;i++)scanf("%d",&goal[i]);ans = bfs();if(ans==-1)printf("Impissible\n");elseprintf("%d\n",ans);return 0;}


0 0
原创粉丝点击