1. 程式人生 > >推箱子的最優路徑

推箱子的最優路徑

大家一定玩過“推箱子”這個經典的遊戲。具體規則就是在一個N*M的地圖上,有1個玩家、1個箱子、1個目的地以及若干障礙,其餘是空地。玩家可以往上下左右4個方向移動,但是不能移動出地圖或者移動到障礙裡去。如果往這個方向移動推到了箱子,箱子也會按這個方向移動一格,當然,箱子也不能被推出地圖或推到障礙裡。當箱子被推到目的地以後,遊戲目標達成。現在告訴你遊戲開始是初始的地圖佈局,請你求出玩家最少需要移動多少步才能夠將遊戲目標達成。

**輸入描述**:
每個測試輸入包含1個測試用例
第一行輸入兩個數字N,M表示地圖的大小。其中0<N,M<=8。
接下來有N行,每行包含M個字元表示該行地圖。其中 . 表示空地、X表示玩家、*表示箱子、#表示障礙、@表示目的地。
每個地圖必定包含1
個玩家、1個箱子、1個目的地。

輸出描述:

輸出一個數字表示玩家最少需要移動多少步才能將遊戲目標達成。當無論如何達成不了的時候,輸出-1。

例子

4 4
....
..*@
....
.X..

輸出結果:3

6 6
...#..
......
#*##..
..##.#
..X...
[email protected]#...
輸出結果為 11

下面是程式碼,有詳細註解,核心是佇列的資料結構和BFS搜尋
程式在VS2015下編譯通過。

#include<iostream>
#include<queue>
#include<string>
using namespace std; int state[10][10][10][10];//四維陣列表示人和箱子的位置狀態,開始全為0 struct q { int px, py, bx, by; q(int x, int y, int bx, int by) :px(x), py(y), bx(bx), by(by) {} }; int moves[4][2] = { {0,1},{0,-1},{-1,0},{1,0} };//四個方向 char map[10][10];//地圖陣列 int chx, chy, cbx, cby, ex, ey, n, m;//分別表示當前人的位置,盒子的位置,終點位置,以及地圖尺寸。
bool bound(int x,int y)//邊界檢查,遇到不合理的位置返回真 { if (x < 0 || y < 0 || x >= n || y >= m || map[x][y] == '#') return true; else return false; } int bfs() { state[chx][chy][cbx][cby] = 1;//當前其實狀態位置設步數為1 q temp(chx, chy, cbx, cby); queue<q> que; //狀態佇列 que.push(temp);//初始狀態入棧 while (que.size()) //只要佇列不為空就一直尋找 { temp = que.front();//獲取首元素 que.pop();//首元素彈出 if (temp.bx == ex&&temp.by == ey) return state[temp.px][temp.py][temp.bx][temp.by]-1;//如果箱子在終點,結束,返回步數 for (int i = 0; i < 4; i++)//四個方向開始搜尋了 { //先更新人的位置 int px = temp.px + moves[i][0]; int py = temp.py + moves[i][1]; if (bound(px, py)) continue;//如果這個位置非法,探尋其它方向 if (px == temp.bx&&py == temp.by)//如果此時人的位置與箱子的位置重合,說明人應當推動了箱子 { if (bound(temp.bx + moves[i][0], temp.by + moves[i][1])) continue;//如果箱子移動的位置不合法,則重新探尋其它方向 state[px][py][temp.bx + moves[i][0]][temp.by + moves[i][1]] = state[temp.px][temp.py][temp.bx][temp.by] + 1;//箱子推動,則人和箱子位置改變,記錄新狀態 que.push(q(px, py, temp.bx + moves[i][0], temp.by + moves[i][1]));//新狀態入棧 } else//人沒有推動箱子 { if (state[px][py][temp.bx][temp.by])//如果移動後的狀態出現過,則重新搜尋新方向 continue; state[px][py][temp.bx][temp.by] = state[temp.px][temp.py][temp.bx][temp.by] + 1; //沒有走過這條路就走著試試 que.push(q(px, py, temp.bx, temp.by));//更新狀態 } } } return -1;//如果所有位置都試過了,沒有找到,說明不存在 } int main() { cin >> n >> m; //cin.clear(); for (int i = 0; i < n; i++) { scanf_s("%s", map[i],m+1); } for (int i = 0; i < n; i++)//初始化人,箱子,終點的位置 { for (int j = 0; j < m; j++) { if (map[i][j]=='*') { cbx = i; cby = j; } else if (map[i][j] == 'X') { chx = i; chy = j; } else if (map[i][j] == '@') { ex = i; ey = j; } } } cout << bfs() << endl; return 0; }

題目來自牛客網,若侵權,則請聯絡我,我將刪除

相關推薦

箱子路徑

大家一定玩過“推箱子”這個經典的遊戲。具體規則就是在一個N*M的地圖上,有1個玩家、1個箱子、1個目的地以及若干障礙,其餘是空地。玩家可以往上下左右4個方向移動,但是不能移動出地圖或者移動到障礙裡去。如果往這個方向移動推到了箱子,箱子也會按這個方向移動一格,當然

Matlab實現Flyod求短距離及存儲路徑

font -1 .cn 技術分享 logs spa image 之間 最短距離 Matlab實現Flyod求最短距離及存儲最優路徑 一、實際數據   已知圖中所有節點的X、Y坐標。   J01-J62:1-62;   F01-F60:63-122;   Z01-Z06

矩陣從左上角到右下角的路徑使得經過路徑上的權值和大(小)

描述: 有一張藏寶圖,而藏寶圖描述的所在區域(只有一個左上角入口和一個右下角出口)被分為m*n的小區域,並且每一個小區域內都藏有一定數量N(0<=N<=9)的寶貝,但要求只能從當前位置向右邊或者下邊尋找寶貝。如果你非常幸運,得到了這張藏寶圖

深度優先演算法(DFS)遍歷有向無環圖計算路徑

遍歷有向無環圖,尋找最優路徑: 1、假設我們從A點走到B點,可以經過不同的地方,分別用1,2,3,4,5,6表示,A用0表示,B用7表示,從一個地方到另一個地方,中間的路好走的程度用w表示,w越大表示越好走,因此我們可以建立數學模型如下圖1所示: 圖1 2、根據數學模

動態規劃——求數字三角形解和路徑

給定一個由n行數字組成的數字三角形如下圖所示。試設計一個演算法,對於給定的由 n行數字組成的數字三角形, 計算從三角形的頂至底的路徑經過的數字和的最大值。 注意:對於第i層的第j個數字,其所在路徑的下一個數字只能是第i+1層的第j個或第j+1個數字。

ArcEngine 地圖導航 查詢路徑 經緯度座標導航 路徑分析

本文來自CSDN部落格,轉載請標明出處 http//blog.csdn.net/zdb330906531 需求:根據經緯度座標,取得兩個起點與終點,顯示最優路徑實現導航。 參考官方例子後,我在arcMap上已實現效果,要求改為程式碼實現。 實現思路:1、建立路徑 2、新增位

圖的深度優先和廣度優先遍歷及兩點間路徑實現

通用遍歷 參考:https://segmentfault.com/a/1190000002685939 遍歷 圖的遍歷,所謂遍歷,即是對結點的訪問。一個圖有那麼多個結點,如何遍歷這些結點,需要特定策略,一般有兩種訪問策略: 深度優先遍歷 廣度優先遍歷 深度優先 深度優先遍歷

『實踐』Matlab實現Flyod求短距離及儲存路徑

Matlab實現Flyod求最短距離及儲存最優路徑 一、實際資料   已知圖中所有節點的X、Y座標。      圖中的節點編號:矩陣中的編號        J01-J62:1-62;     F01-

Dijastra路徑演算法

關於Dijastra演算法,零零散散地研究了差不多兩天了,基本上弄懂了它的思路和寫程式的思路。演算法思路不是很難(沒理解時還是覺得有點晦澀),程式碼的實現過程,需要反覆推敲和琢磨。目前先寫個初級版本(現在暫時只理解到這個程度) 演算法的思想和方法,各路牛人已經寫過很多,小菜

C++路徑之佛洛依德演算法

#include<iostream> #include<cstring> #include<string> using namespace std; class Graph{ private: int **matri

迷宮矩陣(路徑演算法)

走出迷宮可以使用遞迴或者棧的方式,這裡採用的是棧的方法,迷宮的矩陣如圖,1是牆壁,0是路 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1

路徑算法合集(附python源碼)(原創)

最短 opened 假設 計算機科學 div 長度 特點 font aid 主要的最優(最短)路徑算法: 一、深度優先算法;二、廣度優先算法;三、Dijstra最短路徑;四、floyd最短路徑(待); 一、深度優先算法   圖的深度優先搜索(Depth F

箱子小遊戲《格魯的實驗室》13關 - bfs路徑

rst ace clu end 路徑 我們 prior top other 下載了一款推箱子小遊戲,第13關的時候怎麽也破不了最佳紀錄(最少步數是9而我們最好的方案是10步),因為數據比較小(6*8的方陣),所以寫了個BFS來找最短路。 遊戲的目標是把小黃人推到黃色球,小綠

路徑問題 - 演算法

一、問題描述 有一個 n * n 的矩陣,其中有四個2代表研究院,矩陣中 0 表示道路,1 表示不能走,只可以四個方向走,求找到一點(0點)距離四個研究院中最遠的研究院的距離最近。 測試資料: 5 8 8 4 2 0 0 0 0 0 2 0 0 1 0 0 0 0 0 0 0 0

阿里內題——物流派送員送快遞路徑問題

題目: 如下圖,某物流派送員p,需要給 a、b、c、d. 4個快遞點派送包裹,請問派送員需要選擇什麼樣的路線,才能完成最短路程的派送。假設如圖派送員的起點座標(0,0),派送路線只能沿著圖中的方格邊行駛,每個小格都是正方形,且邊長為1,如p到d的距離就是4。隨機輸入n個派送點座標,求輸出最短

牛客網 短升級路徑 【Dijkstra演算法】+【路徑記錄】

短最優升級路徑 題目描述:遊戲網站提供若干升級補丁,每個補丁大小不一,玩家要升級到最新版,如何選擇下載哪些補丁下載量最小。 輸入: 第一行輸入                 第一個數為使用者版本 第二個數為最新版本,空格分開 接著輸入N行補丁資料       

BFS+優先佇列——迷宮路徑——兩種方法比較及詳細圖解

http://blog.csdn.net/qq_36523667/article/details/78638354 這個連結裡是一道迷宮題。用到了BFS+優先佇列。 我一直百思不得其解優先佇列到底優先在哪了?我感覺和直接bfs沒啥區別?後來證明做法不一樣,思路也不一樣。

基於多點預瞄控制的智慧車輛路徑跟蹤

  基於多點預瞄最優控制的智慧車輛路徑跟蹤 https://mp.weixin.qq.com/s?__biz=MzI1ODYwOTkzNg==&mid=2247492889&idx=1&sn=2b32137f94114fd3996176a3ce78a3ff&chk

證明求路徑問題具有子結構(動態規劃)

演算法導論218頁說了很多來說明最長路徑問題不能用動態規劃演算法,最短路徑可以。在證明最短路徑子問題無關時候應該是預設承認了最短路徑的最優子結構的。可是證明最優子結構需要用到複製貼上法,在用複製貼上法的時候又不免會因為子問題不是無關的從而不能複製貼上,所以不能證明最優子結構,

(路徑算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理與介紹

void empty borde fast 默認 grand else 理解 scan 這一篇博客以一些OJ上的題目為載體。整理一下最短路徑算法。會陸續的更新。。。 一、多源最短路算法——floyd算法 floyd算法主要用於求隨意兩點間的最短路徑。也成