一道迷宫题目的非递归解法

  最近,一直在忙着复习,也没多时间,编程,只能抽出一点时间了(悲剧,哎,在中国当学生就是累,明明教育水平,和理念都很落后,可学校还要培养出,什么都会得全才。)好了不多说了,题目如下:

     有一个长方形的房间里,是用方瓦覆盖的。每个方瓦的颜色是红色或黑色。一名男子正站在一个黑色瓷砖。他从他所站的方瓦上,可以转移到相邻的四个砖之一。但他无法进入红瓦,他只可以进入黑瓦。 
 编写一个程序来计算黑瓦数量,也就是他可以达到的方瓦数(重复上述动作)。

  输入包含多个数据集。一个数据集的包含有在开始的第一行的两个正整数W和H,W和H表示x和y方向上的方瓦数。 W和H的不超过20。之后有H行的数据集,其中每行包括W列字符。每个字符代表着瓷砖的颜色如下: 
‘.’ ——黑色的瓷砖 
‘#’——红色的瓷砖 
‘@’——黑砖上的男子 
 该程序可以循环输入,当输入的W和H都为0时,程序终止。

   我采用一个结构体来模拟迷宫。用广度搜索来确定可已走的结点 代码如下:

 

#include<iostream>
#include<deque>
using namespace std;
struct Node{
 char data;//砖的颜色
 int H;//节点横坐标
 int L;//节点纵坐标
 int v;//节点访问系数
};
void main(){
 int m,n;//输入迷宫的维数 m 表深度 n 表宽度
   cout<<"enter your array's information about length and width:"<<endl;
   cin>>m>>n;
   Node**p=new Node*[m];//动态二维指针
     for(int i=0;i<m;i++)
        p[i]=new Node[n];
           deque<Node*>Q;//定义一个结构体指针型的双端队列
             for(i=0;i<m;i++){
               for(int j=0;j<n;j++){
                        cin>>p[i][j].data;//黑色 or 红色
                       if(p[i][j].data=='@'){//如果是人的初始指针那么进入队列
                           Q.push_front(*(p+i)+j);
                           p[i][j].data='B';
                         }
                        p[i][j].H=i;//初始化迷宫数组 
                        p[i][j].L=j;
                       p[i][j].v=0;
               }
 }
      Node*q=Q.front();
      q->v=1;//修改人的初始位置的访问参数
      int count=1;//计数变量
   while(!Q.empty()){// 根据图的广度搜索遍历原理,先对当前结点的同一层可到达的结点进行访问,然后对下一层,上一层开始访问。
           Node*k=Q.front();//用一个工作指针 来得到队列的“头元素”
          Q.pop_front();//出队,删除头元素
           int a=k->H;//当前元素的横坐标
           int b=k->L;//当前元素的纵坐标
           while(b>-1){//想左找可行结点
                           b--;
                 if(b>-1&&p[a][b].data=='B'&&p[a][b].v==0){//能走通且没走过 入队尾,并计数
                 Q.push_back(*(p+a)+b);
                 p[a][b].v=1;
                count++;
                      }
                  else break;//走不通,或已经走过,则退出。
               }
                      b=k->L;
                while(b<n){//向右找可行的结点
                               b++;
                                if(b<n&&p[a][b].data=='B'&&p[a][b].v==0){
                                Q.push_back(*(p+a)+b);
                                 p[a][b].v=1;
                                 count++;
                              }
                           else break;
                    }
                         b=k->L;
                   if(a+1<m&&p[a+1][b].data=='B'&&p[a+1][b].v==0){//向上一层找可行结点
                           p[a+1][b].v=1;
                             count++;
                         Q.push_back(*(p+a+1)+b);
                      }
                                  if(a-1>-1&&p[a-1][b].data=='B'&&p[a-1][b].v==0){//向下一层找可行结点
                                                            count++;
                                                         Q.push_back(*(p+a-1)+b);
                                                                 p[a-1][b].v=1;
                                           }
  }//搜索结束,count记录下所有可以到达的结点总数
 cout<<"you can getthrougth:"<<count;//输出可走结点个数
}


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值