匿名使用者
1級2011-02-22 回答
本程式的前提是將迷宮儲存在乙個二維陣列裡,可走的地方為0,不可走的地方為1。由於採用回朔演算法,不使用遞迴,所以首先應該建立乙個棧來儲存路徑,路徑是用乙個乙個點來表示的,也就是說棧中儲存的是一系列點的列表。
棧節點型別說明:
struct stacknode
point point;
struct stacknode *next, *prev;//雙向鍊錶形式
棧結構用乙個類(cpointstack)實現,宣告如下:
class cpointstack
public:
void clearstack();//清空棧
void initstack();//初始化棧
bool pop(point &pt);//彈出頂端元素,並給出該點的座標,返回是否彈出成功
bool push(point pt);//將pt點的資訊壓入棧,返回是否壓入成功
cpointstack();
virtual ~cpointstack();
protected:
stacknode *m_psntop;//棧頂指標
stacknode m_snbottom;//棧底,不儲存點資訊
以下為成員函式實現,都是一些資料結構的操作,應該沒什麼好說的:
//構造時初始化棧
cpointstack::cpointstack()
initstack();
//析構時清空棧
cpointstack::~cpointstack()
clearstack();
//將點壓入棧(成功返回true,失敗返回false)
bool cpointstack::push(point pt)
stacknode* newnode = new stacknode;
//是否返回true主要看這裡申請記憶體是否成功
if(!newnode)
return false;
newnode->point = pt;
newnode->prev = m_psntop;
newnode->next = null;
m_psntop->next = newnode;
m_psntop = newnode;
return true;
//將點彈出棧(成功返回true,棧為空則返回false)
bool cpointstack::pop(point &pt)
if(m_psntop == &m_snbottom)//是否返回true主要看這裡棧是否為空
return false;
stacknode *p;
p = m_psntop;
m_psntop = m_psntop->prev;
pt = p->point;
delete p;
m_psntop->next = null;
return true;
//初始化棧
void cpointstack::initstack()
m_psntop = &m_snbottom;
m_snbottom.next = null;
m_snbottom.prev = null;
//清空棧
void cpointstack::clearstack()
stacknode *p;
while(m_psntop != &m_snbottom)
p = m_psntop;
m_psntop = m_psntop->prev;
delete p;
接下來設計怎樣走出這個迷宮,也就是迷宮演算法的主體部分。再次用乙個類實現。
在設計這個類時,我考慮到以下幾點:
1、迷宮入口和出口的座標
2、儲存迷宮的2維陣列
3、獲得路徑的函式
但是實際設計時由於沒有考慮太多問題,只是以設計迷宮演算法和解決乙個具體迷宮為目的,所以沒有考慮動態大小的迷宮,而是將迷宮大小定為601×401。而且在設計迷宮演算法後沒有將路徑順序輸出而是直接在原圖中標識(在儲存迷宮資料的表中設定經過的點為2而將死路點設定為3)。
這樣迷宮類(cgomaze)的宣告為:
class cgomaze
public:
void go();//尋找路徑的函式
point m_ptin;//入口座標
point m_ptout;//出口座標
byte m_btarrmaze[401][601];//儲存迷宮的二維表
cgomaze();
virtual ~cgomaze();
最後讓我們來看一下cgomaze::go()這個函式:
我們模仿人走迷宮時的思路,設定乙個當前點,乙個目標點(下乙個要走的點)。初始情況下當前點為入口,終止條件為當前點為出口,這樣,我們的函式大概結構就出來了。
在從入口到出口的過程中程式對當前點的上、下、左、右四個點依次進行判斷,當發現任乙個方向是未走過的區域時,就將當前點指向那個點進行嘗試,同時將當前點入棧並做標記。而當4個方向都不通或已走過時,則為死路,標記當前點為死路並從棧中彈出上乙個點繼續進行嘗試,這時因為當前點已被標記為死路,則彈出上乙個點時就不會重複這條路,達到尋找正確路徑的效果。
go函式的具體實現如下,其實挺簡單的^_^:
void cgomaze::go()
cpointstack pspath;//儲存路徑的棧
point ptcur = m_ptin, ptnext;//設定當前點為入口
while(ptcur.x != m_ptout.x || ptcur.y != m_ptout.y)//判斷是否已經走出
ptnext = ptcur;//設定目標點為當前點,便於下面偏移
if(m_btarrmaze[ptcur.y - 1][ptcur.x] == 0)
ptnext.y --;//如果上方是空的,則目標點向上偏移
else if(m_btarrmaze[ptcur.y][ptcur.x - 1] == 0)
ptnext.x --;//如果左邊是空的,則目標點向左偏移
else if(m_btarrmaze[ptcur.y + 1][ptcur.x] == 0)
ptnext.y ++;//如果下方是空的,則目標點向下偏移
else if(m_btarrmaze[ptcur.y][ptcur.x + 1] == 0)
ptnext.x ++;//如果右邊是空的,則目標點向右偏移
else
{//這裡是沒有路的狀態
m_btarrmaze[ptcur.y][ptcur.x] = 3;//標記為死路
pspath.pop(ptcur);//彈出上一次的點
continue;//繼續迴圈
//如果有路的話會執行到這裡
m_btarrmaze[ptcur.y][ptcur.x] = 2;//標記當前點為路徑上的點
pspath.push(ptcur);//當前點壓入棧中
ptcur = ptnext;//移動當前點
其實這個部分可以將棧設定為cgomaze類的成員,然後在go函式裡加上:
pspath.clearstack();
這樣就可以用timer來演示走迷宮的過程了
c 迷宮思路 C 簡單迷宮
include include include using namespace std int curpos new int 2 當前位置 int dir 2 記錄朝各個方向走時的下乙個通道快的位置 vector printfoot 記錄足跡 用二位陣列表示迷宮,1位可行走處,0位障礙處 int a...
走出迷宮(C程式設計高階第9周)
問題描述 當你站在乙個迷宮裡的時候,往往會被錯綜複雜的道路弄得失去方向感,如果你能得到迷宮地圖,事情就會變得非常簡單。假設你已經得到了乙個n m的迷宮的圖紙,請你找出從起點到出口的最短路。輸入 第一行是兩個整數n和m 1 n,m 100 表示迷宮的行數和列數。接下來n行,每行乙個長為m的字串,表示整...
又乙個迷宮
有乙個迷宮,迷宮裡有乙個人,迷宮是規格為 n n 的方格,房內特定位置上有障礙物,人處於某一位置,可以選擇向上下左右方向前進,但是要保證面對的不是牆壁或是障礙物,否則無法向前行走。輸入迷宮的規格,乙個正整數 n 2 n 100 佔一行,代表矩陣大小 輸入方形矩陣 n 行 n 列,由 0 和 1 組成...