C++迷宮問(wèn)題的求解算法
本文實(shí)例為大家分享了C++實(shí)現(xiàn)迷宮的具體代碼,供大家參考,具體內(nèi)容如下
一、 實(shí)驗(yàn)?zāi)康模?/strong>
(1) 熟練掌握鏈棧的基本操作及應(yīng)用。
(2) 利用鏈表作為棧的存儲(chǔ)結(jié)構(gòu),設(shè)計(jì)實(shí)現(xiàn)一個(gè)求解迷宮的非遞歸程序。
二、實(shí)驗(yàn)內(nèi)容:
【問(wèn)題描述】
以一個(gè)m×n的長(zhǎng)方陣表示迷宮,0和1分別表示迷宮中的通路和障礙。設(shè)計(jì)一個(gè)程序,對(duì)信任意設(shè)定的迷宮,求出一條從入口到出口的通路,或得出沒有通路的結(jié)論。
【基本要求】
首先實(shí)現(xiàn)一個(gè)鏈表作存儲(chǔ)結(jié)構(gòu)的棧類型,然后編寫一個(gè)求解迷宮的非遞歸程序。求得的通路以三元組(i,j,d)的形式輸出,其中:(i,j)指示迷宮中的一個(gè)坐標(biāo),d表示走到下一坐標(biāo)的方向。如:對(duì)于下列數(shù)據(jù)的迷宮,輸出的一條通路為:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),……。
【測(cè)試數(shù)據(jù)】/strong>
迷宮的測(cè)試數(shù)據(jù)如下:左上角(1,1)為入口,右下角(8,9)為出口。
1 2 3 4 5 6 7 8
0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 1
0 1 1 1 0 0 1 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 1
0 1 1 1 1 0 0 1
1 1 0 0 0 1 0 1
1 1 0 0 0 0 0 0
【實(shí)現(xiàn)提示】
計(jì)算機(jī)解迷宮通常用的是“窮舉求解”方法,即從入口出發(fā),順著某一個(gè)方向進(jìn)行探索,若能走通,則繼續(xù)往前進(jìn);否則沿著原路退回,換一個(gè)方向繼續(xù)探索,直至出口位置,求得一條通路。假如所有可能的通路都探索到則未能到達(dá)出口,則所設(shè)定的迷宮沒有通睡。
可以二維數(shù)組存儲(chǔ)迷宮數(shù)據(jù),通常設(shè)定入口點(diǎn)的下標(biāo)為(1,1),出口點(diǎn)的下標(biāo)為(n,n)。為處理方便起見,可以迷宮的四周加一圈障礙。對(duì)于迷宮任一位置,均可約定有東、南、西、北四個(gè)方向可通。
【選作內(nèi)容】
(1) 編寫遞歸形式的算法,求得迷宮中所有可能的通路;
(2) 以方陣形式輸出迷宮及其通路。
網(wǎng)友提供了一段解決算法:
#include<stdio.h> #include<stdlib.h> #define m 4//行 #define n 4//列 struct xy { int x; int y; }; typedef struct stack { struct xy coordinate; struct stack* next; }stack; void init(stack* p) { p->next = NULL; } void push(stack* p,struct xy cdnt) { stack* temp = p; while(temp->next != NULL) temp = temp->next; stack* newValue = (stack*)malloc(sizeof(struct stack)*1); newValue->coordinate = cdnt; newValue->next = temp->next; temp->next = newValue; } void pop(stack* p) { stack* tempp = p; stack* temp = p->next; while(temp->next != NULL) temp = temp->next,tempp = tempp->next; tempp->next = NULL; free(temp); } void browse(stack* p) { stack* temp = p->next; while(temp != NULL) printf("(%d,%d)\n",temp->coordinate.y,temp->coordinate.x),temp = temp->next; } struct xy getEnd(struct stack* p) { stack* temp = p; while(temp->next != NULL) temp = temp->next; return temp->coordinate; } int getSize(stack* p) { int size = 0; stack* temp = p->next; while(temp != NULL) { size++; temp = temp->next; } return size; } int main() { int path[m+1][n+1] = {0}; int col = 0,row = 0; int i = 0,j = 0; int temp_col = 0,temp_row = 0,t_col = 0,t_row = 0; int flag = 0; struct xy t_pair; //stack A,B; stack* Ahead = (stack*)malloc(sizeof(struct stack)*1); stack* Bhead = (stack*)malloc(sizeof(struct stack)*1); init(Ahead); init(Bhead); for(;i<m;i++) for(j=0;j<n;j++) { printf("input 0 or 1\n"); scanf("%d",&path[i][j]); } i = j = 0; if(path[0][0] == 0 || path[m-1][n-1] == 0) { printf("There is no way\n"); return 1; } while(1) { //檢驗(yàn)是否已經(jīng)到達(dá)末尾 if(col == n-1 && row == m-1 && path[row][col] == 1) { //到達(dá)尾端,意味著找到一條路 flag = 1; printf("Find a way,it's\n"); browse(Ahead); printf("(%d,%d)\n",m-1,n-1); if(getSize(Bhead) != 0) { temp_col = getEnd(Bhead).x; temp_row = getEnd(Bhead).y; while(1) if(getEnd(Ahead).x == temp_col && getEnd(Ahead).y == temp_row) break; else pop(Ahead); col = temp_col + 1; row = temp_row; pop(Bhead); } else return 1; } else//還沒有到末尾的情況 { if(path[row + 1][col] == 1 && path[row][col + 1] == 1) { t_pair.x = col;t_pair.y = row; push(Ahead,t_pair); push(Bhead,t_pair); row++; continue; } //下面不是右邊也不是 if(path[row + 1][col] == 0 && path[row][col + 1] == 0) { if(getSize(Bhead)) { //vector<struct xy>::iterator iter = B.end() - 1; col = getEnd(Bhead).x + 1;row = getEnd(Bhead).y;//回到上一次分叉處,搜索右側(cè)路徑 pop(Ahead); pop(Bhead); continue; } else return 1; } //下面是,右邊不是 if(path[row + 1][col] == 1 && path[row][col + 1] == 0) { t_pair.x = col;t_pair.y = row; push(Ahead,t_pair); row++; continue; } //下面不是,右邊是 if(path[row + 1][col] == 0 && path[row][col + 1] == 1) { t_pair.x = col;t_pair.y = row; push(Ahead,t_pair); col++; continue; } } } if(!flag) printf("There is no way\n"); return 0; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++如何獲取系統(tǒng)信息 C++獲取IP地址、硬件信息等
這篇文章主要為大家詳細(xì)介紹了C++如何獲取系統(tǒng)信,C++獲取IP地址、硬件信息等,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04OpenCV使用GrabCut實(shí)現(xiàn)摳圖功能
Grabcut是基于圖割(graph cut)實(shí)現(xiàn)的圖像分割算法,它需要用戶輸入一個(gè)bounding box作為分割目標(biāo)位置,實(shí)現(xiàn)對(duì)目標(biāo)與背景的分離/分割。本文將使用GrabCut實(shí)現(xiàn)摳圖功能,需要的可以參考一下2023-02-02Clion-MinGW編譯后的exe文件添加ico圖標(biāo)的操作方法
這篇文章主要介紹了Clion-MinGW編譯后的exe文件添加ico圖標(biāo)的操作方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07C語(yǔ)言三個(gè)函數(shù)的模擬實(shí)現(xiàn)詳解
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言三個(gè)函數(shù)的模擬實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03c++中string類型和int類型相互轉(zhuǎn)換的幾種常用方法
我們?cè)诰帉懗绦驎r(shí),經(jīng)常涉及到int與string之間的類型轉(zhuǎn)換,本文主要介紹了c++中string類型和int類型相互轉(zhuǎn)換的幾種常用方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08C++實(shí)現(xiàn)LeetCode(19.移除鏈表倒數(shù)第N個(gè)節(jié)點(diǎn))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(19.移除鏈表倒數(shù)第N個(gè)節(jié)點(diǎn)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語(yǔ)言數(shù)組與地址、數(shù)組名到底是什么詳解
在寫代碼的時(shí)候,我們經(jīng)常用到數(shù)組,那么有沒有想過(guò)數(shù)組名是什么呢?這篇文章主要給大家介紹了關(guān)于C語(yǔ)言數(shù)組與地址、數(shù)組名到底是什么的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06