ACM之八数码问题----BFS搜索----数独游戏的模拟(中)
题目描述;数独游戏的内核模拟
八数码问题;
编号为1到8的8个正方形滑块被摆成3行3列;(有一个格子留空);
每次可以把与空格相邻的滑块(有公共边才算相邻)移到空格中;
而它原来的位置就成为了新的空格;给定初始局面和目标局面(用0表示空格);
你的任务死计算出最少的移动步数;和移动过程;如果无法到达目标局面,则输出-1;
在这节里我们使用c++封装的stl库里面的set类库来帮助我们进行判断是否访问过的操作;
这里用vis.count(s)的返回值来判断s是否在栈里面
用vis.insert(s)将s插入到vis里面;
1 #include <iostream> 2 #include <fstream> 3 #include <set> 4 using namespace std; 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #define MAX 1000000 9 //为什么选择这么大呢?排列数9!; 10 typedef struct Node 11 { 12 int state[9];//存放本状态各个位置的数码值; 13 int fa;//记录父节点的下标; 14 int deepth; 15 int last_x; 16 int last_y; 17 18 }Node; 19 Node q[MAX];//构成状态数组; 20 int i,j,k; 21 set<int> vis; 22 void init_lookup_table() 23 { 24 vis.clear(); 25 } 26 int try_to_insert(int s) 27 { 28 int v=0; 29 for(k=0;k<9;k++) 30 { 31 v=v*10+q[s].state[k]; 32 33 } 34 if(vis.count(v))return 0; 35 vis.insert(v); 36 return 1; 37 } 38 const int dx[4]={-1,1,0,0};//左右上下; 39 const int dy[4]={0,0,-1,1}; 40 int bfs();//广度优先找到目标状态; 41 void print_path(int founded);//根据fa成员,通过递归技术实现状态依次输出; 42 Node destination;//存储目标状态; 43 int main() 44 { 45 /*首先输入起始状态和目标状态*/ 46 memset(q,0,sizeof q); 47 for(i=0;i<9;i++) 48 { 49 scanf("%d",&(q[0].state[i])); 50 } 51 for(i=0;i<9;i++) 52 { 53 scanf("%d",&destination.state[i]); 54 } 55 56 57 /*然后进行搜索并输出*/ 58 int founded=bfs(); 59 if(founded) 60 print_path(founded); 61 else 62 printf("-1\n"); 63 system("pause"); 64 return 0; 65 } 66 int bfs() 67 { 68 69 vis[0].visited=1;//第一个结点访问; 70 vis_cur++;*/ 71 init_lookup_table(); 72 try_to_insert(0); 73 int front=0,rear=1;//用来模拟队列的先进先出,达到广度优先的目的; 74 while (front<rear) 75 { 76 Node &first=q[front]; 77 if (memcmp(first.state,destination.state,sizeof destination.state)==0) 78 {//找到了目标状态; 79 return front; 80 } 81 for(i=0;i<9;i++) 82 if (!first.state[i]) 83 {//找到空格处; 84 break; 85 } 86 87 for(j=0;j<4;j++) 88 {//向四个方向进行转换; 89 Node &new_Node=q[rear]; 90 memcpy(new_Node.state,first.state,sizeof first.state); 91 int new_x=i%3+1+dx[j]; 92 int new_y=i/3+1+dy[j]; 93 94 if (new_x>0&&new_y>0&&new_x<4&&new_y<4) 95 { 96 //位置合法 97 new_Node.state[i]=new_Node.state[i+dx[j]+3*dy[j]];//空格位置; 98 new_Node.state[i+dx[j]+3*dy[j]]=0;//新的状态形成了; 99 new_Node.fa=front; 112 new_Node.deepth=first.deepth+1; 113 new_Node.last_x=dx[j]; 114 new_Node.last_y=dy[j]; 115 if(try_to_insert(rear)) 119 rear++; 120 122 }//if 123 }//for 124 front++; 125
126 }//while 127 return 0; 128 } 129 void print_path(int founded) 130 { 131 if(q[founded].fa!=founded) 132 { 133 print_path(q[founded].fa); 134 } 135 for(i=0;i<3;i++) 136 { 137 for(j=0;j<3;j++) 138 { 139 printf("%d ",q[founded].state[3*i+j]); 140 } 141 printf("\n"); 142 } 143 printf("\n"); 144 }
经过测试发现这个虽然使用stl的类库,把速度提高了8倍以上,但是还是好几分钟;
无法满足我们的要求;
看来要从数据结构上考虑了;下一个博客我们试一下其它的方法;
作者:在河之博
出处:http://www.cnblogs.com/dragonfive/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。