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è)定的迷宮,求出一條從入口到出口的通路,或得出沒(méi)有通路的結(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è)定的迷宮沒(méi)有通睡。
可以二維數(shù)組存儲(chǔ)迷宮數(shù)據(jù),通常設(shè)定入口點(diǎn)的下標(biāo)為(1,1),出口點(diǎn)的下標(biāo)為(n,n)。為處理方便起見(jià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//還沒(méi)有到末尾的情況
{
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語(yǔ)言FlappyBird飛揚(yáng)的小鳥(niǎo)實(shí)現(xiàn)開(kāi)發(fā)流程
因?yàn)樵诩艺撕枚嗵欤S手玩了下自己以前做的一些小游戲,說(shuō)真的,有幾個(gè)游戲做的是真的劣質(zhì),譬如 flappybird 真的讓我難以忍受,于是重做了一波分享給大家2022-11-11
C++11?nullptr實(shí)現(xiàn)初始化空指針
避免產(chǎn)生“野指針”最有效的方法,就是在定義指針的同時(shí)完成初始化操作,本文主要介紹了C++11?nullptr初始化空指針,感興趣的可以了解一下2022-01-01
C++找出字符串中出現(xiàn)最多的字符和次數(shù),時(shí)間復(fù)雜度小于O(n^2)
今天小編就為大家分享一篇關(guān)于C++找出字符串中出現(xiàn)最多的字符和次數(shù),時(shí)間復(fù)雜度小于O(n^2),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12
Qt開(kāi)發(fā)之使用socket實(shí)現(xiàn)遠(yuǎn)程控制
本篇文章將會(huì)介紹下位機(jī)通過(guò)心跳包和上位機(jī)之間進(jìn)行數(shù)據(jù)交互和遠(yuǎn)程功能控制的實(shí)現(xiàn)方法。文中的示例代碼講解詳細(xì),感興趣的可以了解一下2022-11-11
C語(yǔ)言實(shí)現(xiàn)文件版通訊錄的代碼分享
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)文件版通訊錄,主要運(yùn)用了結(jié)構(gòu)體,一維數(shù)組,函數(shù),分支與循環(huán)語(yǔ)句等等知識(shí),需要的可以參考一下2023-01-01
C語(yǔ)言水仙花數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了C語(yǔ)言水仙花數(shù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
VsCode搭建C語(yǔ)言運(yùn)行環(huán)境詳細(xì)過(guò)程及終端亂碼問(wèn)題解決方案
這篇文章主要介紹了VsCode搭建C語(yǔ)言運(yùn)行環(huán)境以及終端亂碼問(wèn)題解決,在VsCode中搭建C/C++運(yùn)行環(huán)境需要先安裝幾個(gè)插件,具體插件文中給大家詳細(xì)介紹,需要的朋友可以參考下2022-12-12
VisualStudio2022編寫C語(yǔ)言的實(shí)現(xiàn)步驟
VisualStudio2022是一款強(qiáng)大的集成開(kāi)發(fā)環(huán)境,可以用來(lái)編寫C語(yǔ)言程序,本文主要介紹了VisualStudio2022編寫C語(yǔ)言的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06
C++ Qt開(kāi)發(fā)之PushButton按鈕組件的使用詳解
Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,本文將重點(diǎn)介紹QPushButton按鈕組件的常用方法及靈活運(yùn)用,感興趣的小伙伴可以學(xué)習(xí)一下2023-12-12

