【演算法】老鼠走迷宮問題的解答

來源:互聯網
上載者:User

一.題目:

      用一個m行n列的二維數組來表示迷宮。數組中每個元素的取值為0或1。其中值0表示通路,值1表示阻塞,迷宮的入口在左上放(1,1)處,出口在右下方(m,n)處。要求求出從迷宮入口到出口有無通路,若有通路則指出其中一條通路的路徑,即輸出找到通路的迷宮數組,其中通路上的“0”用另外一個數字8替換,同時列印出所走通路徑上每一步的位置座標及下一步的方向。

二.演算法說明:

    (1)以二維數組maze[m][n]表示迷宮,並設maze[1][1]處為迷宮入口,maze[m][n]處為迷宮出口,迷宮中的任一位置以maze[i][j]來表示。

    (2)對於迷宮中的每個位置(i,j)處,可能移動的路線可以有八個方向,用一個二維數組move表示這八個方向上座標的增量,並把這八個方向從正東起按順時針方向編上序號,則        
            move[k][0]表示第k個方向上i的增量,

            move[k][1]表示第k個方向上j的增量。

            move數組的方向增量表內容如下:k  1  2  3  4  5  6  7  8

               int move[8][2]={      {0,1},    //正東   i不變   j+1  向右  
                                               {1,1},    //右下    i+1   j+1  
                                               {1,0},    //下  i+1  j不變 
                                               {1,-1},   //
                                               {0,-1},   //
                                               {-1,-1},  //
                                               {-1,0},   //
                                               {-1,1}};  //

     (3)當處於迷宮邊緣時,它的下一個位置不再有八種可能,甚至只有三種可能。所以,為了簡化邊界位置的檢測,將二維數組maze[m][n]擴充到maze[m+2][n+2],且令其四周邊界位置的值均為1。

     (4)電腦解迷宮,要用一步一試探的方法。為此在開始每一步時,都要從正東方向起,沿順時針方向檢測。當探測到某個方向上下一個位置的值為0時,就沿著此方向走一步,當這一步周圍剩下的七個方向的上的值均為1時,則退回一步重新檢測下一方向。在這過程中,建立一個mark[m+2][n+2]數組來記錄某位置是否走過,走過用1記,未走過用0記。據此,可以用遞迴的思路來解決該問題。

     (5)具體的演算法可以概括如下:

             走迷宮過程中,如果當前位置(i,j)(初始以入口為當前位置)已到達出口,即(i,j)=(m,n),則說明已找到一條通路,傳回值1,表示走通,結束遞迴過程;

             如果當前位置的各個方向上都沒有找到通向出口的路徑,則遞迴傳回值0,表示未走通,若此時的位置在入口處,給出“沒有通路”的資訊,結束遞迴;

             如果對當前位置的各個方向依次試探的過程中,發現某個方向的試探位置可以走(即maze與mark數組中該位置的值均為0),則把試探位置作為調用參數遞迴調用走迷宮過程,同時對調用的傳回值進行判斷,若調用傳回值為1,則表示當前位置在走通的路徑上,因此要記錄下該位置,且遞迴返回1。

             在記錄走通的每步位置時,考慮到遞迴的特點,若要正序打出走通的路徑,我們則可以另入口和出口顛倒,即可實現目的。


三,源碼

#include <iostream>using namespace std;const int  m=12,n=15;//迷宮的大小int maze[m+2][n+2]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//輸入迷宮地圖                    1,0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1,                    1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1,                    1,0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,                    1,1,1,0,1,1,1,1,0,1,1,0,1,1,0,0,1,                    1,1,1,0,1,1,1,1,0,1,1,0,1,1,0,0,1,                    1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1,                    1,0,0,1,1,0,1,1,1,0,1,0,0,1,1,1,1,                    1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,                    1,0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,                    1,1,1,0,0,0,1,1,0,1,1,0,0,0,1,0,1,                    1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,1,                    1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1,                    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};int mark[m+2][n+2];//設立迷宮是否走過標誌int move[8][2]={{0,1},    //正東   i不變   j+1  向右                  {1,1},    //右下    i+1   j+1                  {1,0},    //下  i+1  j不變 {1,-1},   //{0,-1},   //{-1,-1},  //{-1,0},   //{-1,1}};  ////方向指標int SeekPath(int x,int y){    int i,g,h;    if(x==1&&y==1) //如果到終點則找到路徑,返回 1return 1;    for (i=0;i<8;i++)//嘗試每一個方向     {       g=x+move[i][0];       h=y+move[i][1]; //探索地點的新座標               if(maze[g][h]==0&&mark[g][h]==0)//如果該地點走得通且沒有被探索過       {           mark[g][h]=1;//將這一地點置為探索過            if(SeekPath(g,h))//從這一地點開始新的探索,如果成功           {              cout<<"("<<g<<","<<h<<")";//則打出這一點的座標              if(move[i][0]==1) cout<<"North->";              if(move[i][0]==-1) cout<<"South->";              if(move[i][1]==1) cout<<"West->";              if(move[i][1]==-1) cout<<"East->";//判斷前一地點到這一地點的方向              cout<<endl;              maze[g][h]=8;//把這一點設為通路               return 1;//返回1            }       }    }    if(x==m&&y==n)     cout<<"No path!"<<endl;//如果最後回到了起點,則說明沒有通路     return 0;//返回0} int main(){    int i,j;    for (i=0;i<m+2;i++)       for (j=0;j<n+2;j++)           mark[i][j]=0;//先將所有通路置為沒有走過               mark[m][n]=1;//將起點置為走過了    if(SeekPath(m,n)) //如果走通     {       cout<<"("<<m<<","<<n<<")"<<endl;//先打出起點座標       maze[m][n]=8;//將起點設為通路       for (i=0;i<m+2;i++)           for (j=0;j<n+2;j++)           {              cout<<maze[i][j]<<" ";              if(j==n+1)   cout<<endl;           }//列印出走通後的迷宮    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.