zoukankan      html  css  js  c++  java
  • 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倍以上,但是还是好几分钟;

    无法满足我们的要求;

    看来要从数据结构上考虑了;下一个博客我们试一下其它的方法;

  • 相关阅读:
    pycharm安装破解
    flask动态生成csv
    使用django开发restful接口
    python matplotlib显示中文和负数符号
    locust性能测试02—检查点
    locust性能测试01—初体验
    Mac中配置jmeter+grafana监控
    CF731E Funny Game
    CF197A Plate Game
    luoguP1823 [COI2007] Patrik 音乐会的等待
  • 原文地址:https://www.cnblogs.com/dragonfive/p/2979545.html
Copyright © 2011-2022 走看看