迷宮求解(遞歸)

首先來看一下迷宮簡易圖
????????????????????????????這里寫圖片描述
????我們用 0 來表示該位置是墻, 用 1 來表示該位置是路. 所以, 我們在處理迷宮問題的時候可以將其看成一個二維數組即可, 而對應的每一條路我們可以用坐標的形式將其表示, 所以還需要有一個結構體來描述對應的點的
1. 相關數據結構

typedef struct Maze 
{int map[MAX_ROW][MAX_COL];
}Maze;
typedef struct Point
{int row;int col;
}Point;

2.迷宮初始化
????所謂的初始化迷宮就是將這個二維數組初始化, 我們自己定義一個二維數組, 然后將其每一個值賦值給我們的迷宮地圖即可

void MazeInit(Maze* maze)
{if(maze == NULL){return;}int Map[MAX_ROW][MAX_COL] = {{0, 1, 0, 0, 0, 0},{0, 1, 0, 0, 0, 0},{0, 1, 0, 0, 0, 0},{0, 1, 1, 1, 1, 0},{0, 0, 0, 1, 1, 0},{0, 0, 0, 1, 0, 0}};int row = 0;int col = 0;for(; row < MAX_ROW; row++){for(col = 0; col < MAX_COL; col++){maze -> map[row][col] = Map[row][col];}}
}

3.迷宮探索
????迷宮探索即就是從給出的迷宮入口開始, 一直往后探索, 直到找到出口為止. 我們利用函數在遞歸的過程中會形成棧楨的特性, 依次將我們所探索的為位置進行壓棧, 在此過程中, 我們必須得判斷當前的點是否合法, 同時必須判斷當前的點是否可以落腳, 如果可以落腳, 就現將該位置標記, 然后判斷當前位置是否是出口, 如果是出口, 說明迷宮探索完畢, 如果不是出口, 那么我們就得必須找下一個可以落腳的位置, 即我們依次按照順時針的方向依次遍歷當前位置四周的四個點(up, rught, down, left), 只要我們發現有一個點可以落腳, 我們就將當前位置對應的點入棧(調用函數本身), 當四個方向都已經走完了, 那么我們就得往回退, 即就是對應的出棧過程了.具體如下圖
????????????????????????????????????這里寫圖片描述

void _GetPath(Maze* maze, Point cur, Point entry)
{if(maze == NULL){return;}if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col > MAX_COL){return;}if(entry.row < 0 || entry.row >= MAX_ROW || entry.col < 0 || entry.col >= MAX_COL){return;}printf("(%d, %d)\n", cur.row, cur.col);//判斷當前點是否可以落腳if(CanStay(maze, cur))//如果可以落腳, 就給當前位置標記//如果當前點是出口, 則說明找到了一條路按順時針方向探測四個相鄰點, 遞歸調用函數自身, {Mark(maze, cur);if(IsExit(maze, cur, entry)){printf("找到了一條路\n");return;}//遞歸時更新 cur, (每次遞歸時, 這里的點是下次要走的點, 無論能不能走交給遞歸判斷)Point up = cur;up.row -= 1;_GetPath(maze, up, entry);Point right = cur;right.col += 1;_GetPath(maze, right, entry);Point down = cur;down.row += 1;_GetPath(maze, down, entry);Point left = cur;left.col -= 1;_GetPath(maze, left, entry);}else{return;}
}void GetPath(Maze* maze, Point entry)
{if(maze == NULL){return;//非法輸入}if(entry.row < 0 || entry.row >= MAX_ROW || entry.col < 0 || entry.col >= MAX_COL){return;}//輔助完成遞歸_GetPath(maze, entry, entry);MazePrint(maze);
}

4.判斷是否可以落腳
???? 即先判斷迷宮數據結構是否輸入合法, 接下來就是判斷當前位置是否合法, 如果不合法就退出, 如果當前位置對應的值是 1, 則說明能落腳, 否則就說明不能落腳.

int CanStay(Maze* maze, Point cur)
{if(maze == NULL){return 0;}if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col >= MAX_COL){return 0;}if(maze -> map[cur.row][cur.col] == 1){return 1;}return 0;
}

5.判斷出口
????如果該位置到達迷宮邊界, 并且不等于入口位置, 則說明到達出口

int IsExit(Maze* maze, Point cur, Point entry)
{if(maze == NULL){return 0;}if(cur.row == entry.row && cur.col == entry.col){return 0;}if(cur.row == MAX_ROW -1 || cur.row == 0 || cur.col ==MAX_COL -1 || cur.col == 0){return 1;}return 0;
}

6.標記
????將當前位置的值賦值為2

void Mark(Maze* maze, Point cur)
{if(maze == NULL){return;}if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col >= MAX_COL){return;}maze -> map[cur.row][cur.col] = 2;
}

7.打印迷宮函數

void MazePrint(Maze* maze)
{if(maze == NULL){return;//非法輸入}int row = 0;int col = 0;for(; row < MAX_ROW; row++){for(col = 0; col < MAX_COL; col++){printf("%2d ", maze -> map[row][col]);}printf("\n");}
}

????依次將回溯點打印出來,運行結果如圖
????????????????????????????????這里寫圖片描述

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

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

相關文章

CodeForces - 786C——二分+模擬?

【題目描述】 Rick and Morty want to find MR. PBH and they cant do it alone. So they need of Mr. Meeseeks. They Have generated n Mr. Meeseeks, standing in a line numbered from 1 to n. Each of them has his own color. i-th Mr. Meeseeks color is ai.Rick and M…

迷宮求解(非遞歸)

上篇文章寫出了利用函數形成棧楨的特性完成迷宮求解問題, 本篇文章我們自己手動維護一個棧, 其進行出棧, 入棧, 取棧頂元素, 來完成迷宮求解尋路的過程 ????思路和以前一樣, 首先, 我們先定義一個棧, 對其初始化, 同時, 定義一個迷宮地圖, 對該地圖進行初始化, 先判斷當前…

數據結構練習——雙向鏈表

http://www.cnblogs.com/-Lei/archive/2012/04/10/2440399.html 復習一下數據結構。。。。說不準下個星期就用上了 只不過寫的很簡單&#xff0c;沒有封裝 DoubleLinkList.h #ifndef GUARD_DoubleLinkList_h #define GUARD_DoubleLinkList_h#include <stdio.h>struct Li…

CodeChef - DGCD——樹鏈剖分+差分

【題目描述】 Youre given a tree on N vertices. Each vertex has a positive integer written on it, number on the ith vertex being vi. Your program must process two types of queries :1. Find query represented by F u v : Find out gcd of all numbers on the uniq…

UVa272-TeX中的引號

【題目描述】 傳送門 【題目分析】 今天開始刷紫書的題目啦 這道題很簡單&#xff0c;需要注意的是cgetchar()需要加上括號&#xff0c;因為賦值語句的優先級比判等低 而且書中說好像最好用整型變量&#xff0c;因為EOF的值為-1&#xff0c;在字符變量中沒有這個值。&#xf…

C++中友元(友元函數和友元類)的用法和功能

http://blog.csdn.net/adriano119/article/details/5914443/ 采用類的機制后實現了數據的隱藏與封裝&#xff0c;類的數據成員一般定義為私有成員&#xff0c;成員函數一般定義為公有的&#xff0c;依此提供類與外界間的通信接口。但是&#xff0c;有時需要定義一些函數&#x…

線程的終止分離

1.線程的終止 注意該函數是針對用戶級別的, 其中 retal 必須指向一個全局變量, 或者是一個 malloc 分配的, 因為如果是線程的局部變量, 當該線程退出時, 其他線程不能得到這個變量, 因為線程的局部變量各自私有 2. 現成的取消 其中thread是線程的 tid 3.線程的等待與分離 (1)…

UVa10082

【題目描述】 傳送門 【題目分析】 同樣是一道模擬&#xff0c;但是如何巧妙快速的解決仍然不簡單。通過這道題告訴我們對于復雜確定的對應關系我們要靈活運用常量數組。 同時還需要注意的一個小問題就是字符串數組中的"//"指的是轉義后的單斜杠&#xff0c;如果只…

C語言中的深拷貝和淺拷貝

http://www.cnblogs.com/zhanggaofeng/p/5421804.html C語言中的深拷貝和淺拷貝 //C語言中的深拷貝和淺拷貝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>typedef struct _student{char name[30];char *title;…

死鎖的產生和避免

1.死鎖產生的四個必要條件 (1)互斥條件&#xff1a;資源是獨占的且排他使用&#xff0c;進程互斥使用資源&#xff0c;即任意時刻一個資源只能給一個進程使用&#xff0c;其他進程若申請一個資源&#xff0c;而該資源被另一進程占有時&#xff0c;則申請者等待直到資源被占有者…

UVa401

【題目描述】 傳送門 【題目描述】 嘻嘻&#xff0c;自己做直接AC還是比較開心的。當然有一部分原因是之前看書的時候詳細看過這個題的代碼&#xff0c;但是這已經快一年了&#xff0c;應該說做出這道題憑借的是自己的能力吧。回過身去看了一下書中的代碼發現自己寫的不算復…

gethostbyname() 函數說明

https://www.cnblogs.com/cxz2009/archive/2010/11/19/1881611.html gethostbyname()函數說明——用域名或主機名獲取IP地址 包含頭文件#include <netdb.h>#include <sys/socket.h>函數原型struct hostent *gethostbyname(const char *name);這個函數的傳入值是域…

求解迷宮最短路徑

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("…

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); /*調用指針數組…