求解迷宮最短路徑

1. 多通路迷宮初始化

????先構建一個多通路迷宮,并且對其初始化

void MazeInitShortPath(Maze* maze)
{if(maze == NULL){return;}int row = 0;int col = 0;for(; row < MAX_COL; row++){for(col = 0; col < MAX_COL; col++){maze -> map[row][col] = Map[row][col];}printf("\n");}
}

????????????????????????這里寫圖片描述

2. 定義一個棧并且打印

/** * @brief* * @用來測試迷宮棧* @param msg       */
void SeqStackDebugPrint(SeqStack* short_path, char* msg)
{printf("[%s]\n", msg);if(short_path == NULL || msg == NULL){return;}int i =0;for(;i < short_path -> size; i++){printf("(%d, %d)\n", short_path -> data[i].row, short_path -> data[i].col);}printf("\n");
}
3. 遞歸找通路

????在次過程中, 用到的思路和上一篇的迷宮求通路的思路一樣. 即就是利用遞歸的方式實現.不過因為此次有好多個出口, 所以我們每次都需要定義兩個棧, 保存當前路徑, 以及最短路徑, 最后將最短路徑中的內容打印出來.首先, 先判斷當前點是否可以落腳, 如果不能落腳, 就直接退出, 如果可以落腳, 就現將當前位置標記, 然后將其入棧, 再判斷當前位置是否是出口, 如果是出口就得判斷當前棧和最短路徑棧中它們兩個哪個路徑短, 如果當前路徑比最短路徑的步數少, 或者最短;路徑棧為空, 就用當前棧代替保存最短路徑的那個棧, 同時需要進行回溯, 將保存當前路徑的棧出棧.如果當前位置不是出口, 就對當前位置周圍的四個位置進行探索,直到找到出口為止. 如果當前位置周圍的四個點都已經探索, 此時就需要回溯了, 回溯的過程中也需要將保存當前位置的棧的元素出棧.

//輔助遞歸
void _GetShortPath(Maze* maze, Point cur, Point entry, SeqStack* cur_path, SeqStack* short_path)
{if(maze == NULL){return;}printf("(%d, %d)\n", cur.row, cur.col);//1. 判斷當前是否可以落腳if(CanStay(maze, cur) == 0){return;}//2. 能落腳就將其標記, 插入到cur_pathMark(maze, cur);SeqStackPush(cur_path, cur);//3. 判定當前是否是出口//b) 如果當前路徑沒有short_path短, 就回溯找其他路徑, 在回溯前也需要將 cur_path 出棧if(IsExit(maze, cur, entry)){printf("找到了一條較短的路\n");if(cur_path -> size < short_path -> size || short_path -> size == 0){//a) 如果是出口, 說明找到了一條路, 拿著當路徑和short_path 比較, 如果當前路徑比 short_path 路徑短, //應當前路徑代替 short_path(打擂臺), 或者 short_path 是個空棧, 就用當前棧代替short_path, 代替完//需要回溯, 找其他路徑SeqStackAssgin(short_path, cur_path);}SeqStackPop(cur_path);return;}//4. 當前點不是出口, 嘗試找四個方向(探測四個方向)Point up = cur;up.row -= 1;_GetShortPath(maze, up, entry, cur_path, short_path);Point right = cur;right.col += 1;_GetShortPath(maze, right, entry, cur_path, short_path);Point down = cur;down.row += 1;_GetShortPath(maze, down, entry, cur_path, short_path);Point left = cur;left.col -= 1;_GetShortPath(maze, left, entry, cur_path, short_path);//5. 如果四個方向都探測過了, 回溯返回到上一個點, 同時 cur_path 出棧 SeqStackPop(cur_path);
}
void GetShortPath(Maze* maze, Point entry)
{if(maze == NULL){return;}if(entry.row < 0 || entry.row >= MAX_ROW || entry.col < 0 || entry.col >= MAX_COL){return;}SeqStack cur_path;SeqStack short_path;SeqStackInit(&cur_path);SeqStackInit(&short_path);_GetShortPath(maze, entry, entry, &cur_path, &short_path);SeqStackDebugPrint(&short_path, "打印棧內容");printf("%d\n", short_path.size);
}
4. 棧的復制

????為了代碼實現的簡單, 我們定義兩個棧, from, to, from比to的元素要少. 在復制之前, 將to 的內存先進行釋放, 然后對to進行動態內存分配, 接著將 from 結構體的所有信息全部復制到 to 中,最后將from中的元素依次復制給 to即可

void SeqStackAssgin(SeqStack* to, SeqStack* from)
{if(from == NULL || to == NULL){return;}SeqStackDestroy(to);to -> data = (Point*)malloc(from -> capacity * sizeof(SeqStackType));to -> size = from -> size;int i = 0;for(; i < from -> size; i++){to -> data[i] = from -> data[i];}
}

????????????????????????這里寫圖片描述
????????????????????????這里寫圖片描述

5. 總結

????總結一下, 整體思路如下. 先定義兩個棧 cur_path , shrott_path, 前者保存當前路徑.后者保存最短路徑, 接著 判斷當前位置是否可以落腳, 如果不能落腳就直接返回, 如果可以落腳就將當前位置標記, 然后將當前點進行入棧, 入棧到 cur_path中, 接下來判斷當前位置是否為出口, 如果是出口, 就比較 cur_path 和 short_path 之間的長度, 如果 cur_path的元素少于 short_path 的元素或者 short_path 為空, 就用cur_path 代替 short_path, 然后將當前 cur_path 棧出棧, 接著進行回溯. 如果當前棧的元素個數大于 short_path棧的元素, 就將 cur_path 出棧, 然后進行回溯; 如果當前位置不是出口, 就按照順序(順時針)探測當前位置周圍的四個點, 如果當前位置周圍的四個點都已經探測, 此時說明進入了死胡同, 就需要回溯, 回溯之前不要忘記將當前的棧 cur_path 進行出棧, 最后,當遞歸結束時, 打印 short_path棧, 因為該棧里保存的就是最短路徑

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384032.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384032.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384032.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UVa340

【題目描述】 傳送門 【題目分析】 題目理解以后十分簡單&#xff0c;但是這題面實在讓人自閉&#xff0c;這么簡單的題目啦啦啦啦說了那么多&#xff0c;實在是看不懂。&#xff08;幸虧我看了書理解了題目的意思&#xff0c;要不然。。&#xff09;還是要鍛煉自己的讀題能…

C語言:結構體中一級指針和二級指針的創建與釋放示例

http://blog.csdn.net/Bixiwen_liu/article/details/53610952 這幾天把C語言鞏固了一下&#xff0c;作為一門最基本的編程語言&#xff0c;C語言還是相當基礎和非常重要的&#xff0c;個人認為C語言還是很有必要學好吃透的。 今天寫的話題是結構體結構體中一級指針和二級指針的…

帶環迷宮求最短路徑

前面介紹了簡單的迷宮求解問題, 今天我們就對帶環迷宮求出它的最短路徑 1.首先來看一個帶環迷宮的簡單地圖 在這張迷宮地圖中,我們規定入口點的位置entry的坐標是 (0, 1), 同時, 我們給入口點傳一個非法坐標,作為入口點的前一個位置(-1, -1). 接下來的思路就和上一篇的思路是一…

UVa1583

【題目描述】 傳送門 【題目分析】 我以為很簡單就寫了一個暴力沒有想到超時了。應該是T是非常大的所以必須得打表&#xff0c;將所有的結果都儲存起來然后直接輸出。 以后遇到這種可以一下算出所有結果的多組數據最好還是算出所有的結果然后再輸出答案。 【AC代碼】 #inc…

C 結構體嵌套一級指針 二級指針 動態分配內存

https://blog.csdn.net/xielinhua88/article/details/51364623 點擊打開鏈接 #define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> //結構體嵌套一級指針 二級指針 動態分配內存 typedef struct _Teacher { int ag…

線程的同步與互斥

1. 互斥量 在Linux 下線程使用的都是局部變量, 而我們知道, 每一個線程都獨立擁有自己的一個棧, 而這些局部便令就在棧中,而線程的創建就是為了實現通信, 此時線程之間無法共享這些變量 ????為了使得線程之間能夠共享數據, 一次我們可以創建一個全局變量, 此時線程都在進程…

二級指針與指針數組的關系

http://blog.csdn.net/shuaishuai80/article/details/6129742 #include <stdio.h> void test(char *argv[]); int main(void) { char *argv[3]{{"abcdefg"},{"1234567"},{"q1w2e3r"}}; test(argv); /*調用指針數組…

UVa1584

【題目描述】 傳送門 【題目分析】 也是一道簡單的模擬題&#xff0c;1A嘿嘿嘿。 再看書發現和書上的做法差不多。 【AC代碼】 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<cstd…

cf#582div3 D——暴力

【題目描述】 The only difference between easy and hard versions is the number of elements in the array.You are given an array a consisting of n integers. In one move you can choose any ai and divide it by 2 rounding down (in other words, in one move you c…

C語言 可變參數

http://www.cnblogs.com/zhanggaofeng/p/6434554.html //可變參數 #include <stdio.h> #include <stdlib.h> #include <string.h> //引用頭文件 #include <stdarg.h>/* va_list用于聲明一個變量&#xff0c;我們知道函數的可變參數列表其實就是一個字符…

UVa1585

【題目描述】 傳送門 【題目分析】 氵 【AC代碼】 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<cstdlib> #include<set> #include<map> #include<vector>u…

c語言經典算法——查找一個整數數組中第二大數

https://www.cnblogs.com/dootoo/p/4473958.html 題目&#xff1a; 實現一個函數&#xff0c;查找一個整數數組中第二大數。 算法思想&#xff1a; 設置兩個變量max1和max2&#xff0c;用來保存最大數和第二大數&#xff0c;然后將數組剩余的數依次與這兩個數比較&#xff0c;如…

進程間關系和守護進程

一. 進程組/作業/會話 1.進程組 每一個進程除了有一個進程ID之外, 還屬于一個進程組. 進程是一個或多個進程的集合. 通常, 它們與同一個作業向關聯, 可以接收來自同一個終端下的各種命令,信號. 每一個進程組都有唯一的進程組 ID. 每一個進程組都可以有一個組長進程. 組長進程的…

UVa1586

【題目描述】 傳送門 【題目分析】 氵 【AC代碼】 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<cstdlib> #include<set> #include<map> #include<vector> …

猴子偷桃問題

http://blog.csdn.net/snow_5288/article/details/52561882 問題描述&#xff1a; /*有一群猴子&#xff0c;去摘了一堆桃子*/ /*商量之后決定每天吃剩余桃子的一半*/ /*當每天大家吃完桃子之后&#xff0c;有個貪心的小猴都會偷偷再吃一個桃子*/ /*按照這樣的方式猴子們每天都…

UVa1225

【題目描述】 傳送門 【題目分析】 做題做多了慢慢都忘記暴力了&#xff0c;想要快速算出來&#xff0c;找到規律&#xff0c;但是找來找去好復雜的都沒有找到&#xff0c;然后寫了一個不能再暴力的寫法&#xff0c;就過了。。。 我還是覺得如果數據范圍變成1e9那種級別的還…

linux 線程學習之條件變量

http://blog.csdn.net/hemmanhui/article/details/4417433 互斥鎖&#xff1a;用來上鎖。 條件變量&#xff1a;用來等待&#xff0c;當條件變量用來自動阻塞一個線程&#xff0c;直到某特殊情況發生為止。通常條件變量和互斥鎖同時使用。 函數介紹&#xff1a; 1&#xff0e;…

UVa455

【題目描述】 傳送門 【題目分析】 就是一個簡單的暴力&#xff0c;只是需要注意輸出格式比較毒瘤。 【AC代碼】 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #i…

網絡相關基礎概念

一. 相關基礎概念 1.計算機網絡的特點 (1)連通性:計算機網絡使得上網的用戶都能夠彼此相連, 好像用戶的計算機可以直接相連 ????(2)資源共享:資源共享可以是信息共享, 軟件共享, 硬件共享等等. 由于網絡的存在, 使得用戶感覺資源就在自己身邊 2. 網絡 網絡是由若干結點和…

linux線程同步(2)-條件變量

https://www.cnblogs.com/yuuyuu/p/5140875.html linux線程同步(2)-條件變量 一.概述 上一篇&#xff0c;介紹了互斥量。條件變量與互斥量不同&#xff0c;互斥量是防止多線程同時訪問共享的互斥變量來保護臨界區。條件變量…