• 迷宫问题


    书里面的例题,这里记录一下代码。

    如下图所示,给出一个N*M的迷宫图和一个入口、一个出口。编序打印一条从迷宫入口到出口的路径。这里黑色方块的单元表示走不通(用-1表示),白色方块的单元表示可以走(用0表示)。只能往上、下、左、右四个方向走。如果无路则输出“no way.”。

    【算法分析】

    只要输出一条路径即可,所以是一个经典的回溯算法问题,下面分别是回溯(深搜)程序和广搜程序。

    深搜代码:

     1 #include <stdio.h>
     2 
     3 #define maxN 1003
     4 #define maxM 1003
     5 
     6 int n,m,desX,desY,souX,souY,totalStep,a[maxN*maxM],b[maxN*maxM],map[maxN][maxM];
     7 bool f;
     8 
     9 int move(int x, int y,int step)
    10 {
    11     map[x][y]=step;         //走一步,作标记,把步数记下来
    12     a[step]=x;  b[step]=y;  //记路径
    13     if((x==desX)&&(y==desY))
    14     {
    15         f=1;
    16         totalStep=step;
    17     }
    18     else
    19     {
    20         if( (y!=m)&&(map[x][y+1]==0) )  move(x,y+1,step+1);         //向右
    21         if( (!f)&&(x!=n)&&(map[x+1][y]==0) )  move(x+1,y,step+1);   //往下
    22         if( (!f)&&(y!=1)&&(map[x][y-1]==0) )  move(x,y-1,step+1);   //往左
    23         if( (!f)&&(x!=1)&&(map[x-1][y]==0) )  move(x-1,y,step+1);   //往上
    24     }
    25 }
    26 
    27 int main(int argc, char *argv[])
    28 {
    29     int i,j;
    30     freopen("migong2.in","r",stdin);
    31     //freopen("migong.out","w",stdout);
    32     scanf("%d%d",&n,&m);  //n行m列的迷宫
    33     for (i=1;i<=n;i++)    //读入迷宫,0表示通,-1表示不通
    34         for (j=1;j<=m;j++)
    35             scanf("%d",&map[i][j]);
    36     scanf("%d%d%d%d",&souX,&souY,&desX,&desY);//出发点和目的地点 
    37     f=0;//f=0表示无解;f=1表示找到了一个解
    38     
    39     move(souX,souY,1);
    40     
    41     if(f)
    42     {
    43         for (i=1;i<=totalStep;i++)  //输出走迷宫的路径
    44             printf("%d,%d
    ",a[i],b[i]);
    45     }
    46     else  printf("no way.
    ");
    47     /**/
    48     return 0;
    49 }

    上述代码搜索结果:

    广搜代码1:

     1 #include<iostream>
     2 using namespace std;
     3 int u[5]={0,0,1,0,-1},//右,下,左,上 
     4     w[5]={0,1,0,-1,0};
     5 int n,m,i,j,desx,desy,soux,souy,head,tail,x,y,a[51],b[51],pre[51],map[51][51];
     6 bool f;
     7 int print(int d)
     8 {
     9     if (pre[d]!=0) print (pre[d]); //递归输出路径
    10     cout<<a[d]<<","<<b[d]<<endl;
    11 }
    12 int main()
    13 {
    14     int i,j;
    15     freopen("mgong.in","r",stdin);
    16     freopen("mgong.out","w",stdout);
    17     cin>>n>>m;          //n行m列的迷宫
    18     for (i=1;i<=n;i++)  //读入迷宫,0表示通,-1表示不通
    19         for (j=1;j<=m;j++) 
    20             cin>>map[i][j];
    21     cin>>soux>>souy;    //入口
    22     cin>>desx>>desy;    //出口
    23     head=0;
    24     tail=1;
    25     f=0;
    26     map[soux][souy]=-1;
    27     a[tail]=soux;  b[tail]=souy; pre[tail]=0;
    28     while (head!=tail)  //队列不为空
    29     {
    30         head++;
    31         for(i=1;i<=4;i++)  //4个方向
    32         {
    33             x=a[head]+u[i];  y=b[head]+w[i];
    34             if((x>0)&&(x<=n)&&(y>0)&&(y<=m)&&(map[x][y]==0))
    35             {                                                  //本方向上可以走
    36                 tail++;
    37                 a[tail]=x;  b[tail]=y;  pre[tail]=head;
    38                 map[x][y]=-1;
    39                 if ((x==desx)&&(y==desy))     //扩展出的结点为目标结点
    40                 {
    41                     f=1;
    42                     print(tail);
    43                     break;
    44                 }
    45             }
    46         }
    47         if(f) break;
    48     }
    49     if(!f) cout<<"no way."<<endl;
    50     return 0;
    51 } 

    广搜代码2:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<queue>
     4 using namespace std;
     5 
     6 struct obj
     7 {
     8     int x,y,index;//index表示坐标(x,y)在pre[]中的坐标 
     9 };
    10 
    11 int u[5]={0,0,1,0,-1},//右,下,左,上 
    12     w[5]={0,1,0,-1,0};
    13 int n,m,map[51][51],desx,desy,soux,souy,a[51],b[51],pre[51],step;
    14 queue<obj> q;
    15 bool f;
    16 
    17 int print(int d)
    18 {
    19     if (pre[d]!=-1) print (pre[d]); //递归输出路径
    20     printf("%d,%d
    ",a[d],b[d]);
    21 }
    22 
    23 int main(int argc, char *argv[])
    24 {
    25     int i,j,x,y;
    26     struct obj temp,temp2;
    27     freopen("mgong.in","r",stdin);
    28     freopen("mgong.out","w",stdout);
    29     cin>>n>>m;          //n行m列的迷宫
    30     for (i=1;i<=n;i++)  //读入迷宫,0表示通,-1表示不通
    31         for (j=1;j<=m;j++) 
    32             cin>>map[i][j];
    33     cin>>soux>>souy;    //入口
    34     cin>>desx>>desy;    //出口
    35     f=0;//f=0表示无解;f=1表示找到了一个解
    36     
    37     map[soux][souy]=-1;
    38     step=0;
    39     a[step]=soux;
    40     b[step]=souy;
    41     pre[step]=-1;//pre[step]=k表示(a[step],b[step])的前驱节点是(a[k],b[k])
    42     temp.x=soux;
    43     temp.y=souy;
    44     temp.index=step;//index表示坐标(x,y)在pre[]中的坐标 
    45     q.push(temp);
    46     
    47     while(!q.empty())
    48     {
    49         temp=q.front(); q.pop();
    50         for(i=1;i<=4;i++)  //4个方向
    51         {
    52             x=temp.x+u[i];  y=temp.y+w[i];
    53             if((x>0)&&(x<=n)&&(y>0)&&(y<=m)&&(map[x][y]==0))
    54             {   //本方向尚可以走
    55                 step++;
    56                 a[step]=x;  b[step]=y;  pre[step]=temp.index;
    57                 temp2.x=x;
    58                 temp2.y=y;
    59                 temp2.index=step;
    60                 q.push(temp2); 
    61                 map[x][y]=-1;
    62                 
    63                 if((x==desx)&&(y==desy))     //扩展出的结点为目标结点
    64                 {
    65                     f=1;
    66                     print(step);
    67                     break;
    68                 }
    69             }
    70         }
    71         if(f) break;
    72     }
    73     if(!f) cout<<"no way."<<endl;
    74     return 0;
    75 }

    上述广搜代码的搜索结果:

  • 相关阅读:
    vs2005发布生成自定义dll
    模拟msn消息提示(右下角)
    通过GridView导出Excel
    在ASP.NET 2.0中直接得到本页面生成的HTML代码
    asp.net实现SQL Server备份还原
    通用分页存储过程算法(.net类实现)
    超链接打开自定义的协议
    GridView技巧2
    sql语句获取本周、本月数据
    asp.net开发自定义控件
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/7228112.html
Copyright © 2020-2023  润新知