推箱子尋求最少步數(廣度優先搜尋)
“推箱子”這個經典的遊戲,具體規則就是在一個N*M的地圖上,有1個玩家、1個箱子、1個目的地以及若干障礙,其餘是空地。玩家可以往上下左右4個方向移動,但是不能移動出地圖或者移動到障礙裡去。如果往這個方向移動推到了箱子,箱子也會按這個方向移動一格,當然,箱子也不能被推出地圖或推到障礙裡。當箱子被推到目的地以後,遊戲目標達成。現在告訴你遊戲開始是初始的地圖佈局,請你求出玩家最少需要移動多少步才能夠將遊戲目標達成。
輸入描述:
每個測試輸入包含1個測試用例 第一行輸入兩個數字N,M表示地圖的大小。其中0<N,M<=50。 接下來有N行,每行包含M個字元表示該行地圖。其中 . 表示空地、X表示玩家、*表示箱子、#表示障礙、@表示目的地。 每個地圖必定包含1個玩家、1個箱子、1個目的地。
輸出描述:
輸出一個數字表示玩家最少需要移動多少步才能將遊戲目標達成。當無論如何達成不了的時候,輸出-1。
輸入例子(一起輸入): 4 4 .... ..*@ .... .X.. 輸出
3 6 6 ...#.. ...... #*##.. ..##.# ..X... [email protected]#...
輸出
11
3 6
.X#[email protected]
.#.*..
......
輸出:
11
完整的程式碼如下:
#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; system("pause"); return 0; }
相關推薦
推箱子尋求最少步數(廣度優先搜尋)
“推箱子”這個經典的遊戲,具體規則就是在一個N*M的地圖上,有1個玩家、1個箱子、1個目的地以及若干障礙,其餘是空地。玩家可以往上下左右4個方向移動,但是不能移動出地圖或者移動到障礙裡去。如果往這個方向移動推到了箱子,箱子也會按這個方向移動一格,當然,箱子也不能被推出地圖或
廣度優先搜尋-最少轉機次數
當你和家人一起去海南旅遊,可是你的城市並沒有直接到達海南的飛機,但是你已經蒐集了很多航班的資訊,現在你希望找到一種乘坐方式,使得轉機次數最少 如何解決呢? 假如你的城市在1號城市,海南在5號城市;現有如下關係: 如何求得1號城市到5號城市的最少轉機
廣度優先搜尋雙佇列通用程式設計模板
廣度優先搜尋主要用於解決求最短問題,如最短路徑,最少變化步數問題等等,思想是從起點出發,按層遍歷,直到搜尋到目標或者已經搜尋完全部區域。通常利用佇列實現廣度優先搜尋,我這裡使用的雙佇列法,用一個佇列cur表示當前層,next表示由當前層擴充套件的下一層,用雙佇列有個好處是我們只需要定義一個全域性
演算法7-6:圖的遍歷——廣度優先搜尋
http://www.dotcpp.com/oj/problem1703.html 題目描述 廣度優先搜尋遍歷類似於樹的按層次遍歷的過程。其過程為:假設從圖中的某頂點v出發,在訪問了v之後依次訪問v的各個未曾被訪問過的鄰接點,然後分別從這些鄰接點出發依次訪問它們的鄰接點,並使“先被訪問的
佇列的JS實現及廣度優先搜尋(BFS)的實現
佇列是先進先出(FIFO)的資料結構,插入操作叫做入隊,只能新增在佇列的末尾;刪除操作叫做出隊,只能移除第一個元素。在JS中,用陣列可以很簡單的實現佇列。 function Queue () { this.queue = []; } // 增加 Queue.prototype.enQueue = f
廣度優先搜尋(鄰接表)
#include <iostream> #include <cstdio> #include <vector> #include <queue> using namespace std; struct Node{ //to 代表每個節點
利用佇列廣度優先搜尋圖
//廣度優先搜尋樹,一定要使用佇列,佇列的特性很好用 import java.util.*; public class Guangduyouxiansousuosuanfa1 { public static void main(String args[]){ Scanner
【BFS】層層遞進—廣度優先搜尋
【BFS】層層遞進—廣度優先搜尋 Breadth First Search 啊哈演算法 迷宮中尋找小哈 #include <iostream> #include <stdio.h> #include <stdlib.h> using na
資料結構——圖(4)——廣度優先搜尋(BFS)演算法思想
廣度優先搜尋 儘管深度優先搜尋具有許多重要用途,但該策略也具有不適合某些應用程式的缺點。 深度優先方法的最大問題在於它從其中一個鄰居出發,在它返回該節點或者是訪問其他鄰居之前,它必須訪問完從出發節點開始的整個路徑。 如果我們嘗試在一個大的圖中發現兩個節點之間的最短路徑,則使用深度優先
python 遞迴深度優先搜尋與廣度優先搜尋演算法模擬實現
一、遞迴原理小案例分析 (1)# 概述 遞迴:即一個函式呼叫了自身,即實現了遞迴 凡是迴圈能做到的事,遞迴一般都能做到! (2)# 寫遞迴的過程 1、寫出臨界條件2、找出這一次和上一次關係3、假設當前函式已經能用,呼叫自身計算上一次的結果,再求出本次的結果 (3)案例分析:求1+2+3+…+n的數和
鄰接表建立無向圖,廣度優先搜尋遍歷輸出
1 #include<stdio.h> 2 #include<string.h> 3 #include <iostream> 4 #include<algorithm> 5 using namespace std; 6 #defin
深度優先搜尋遍歷與廣度優先搜尋遍歷
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
無向圖鄰接連結串列的廣度優先搜尋
個人認為圖的演算法看起來非常簡潔,但是實現起來需要基礎很紮實。因為經常會涉及多種簡單的資料結構,怎樣把他們恰當的串聯起來,不會報那種,空指標了,型別不匹配,實體型別不符合了等等。 在做無向圖鄰接連結串列廣度優先搜尋的時候,寫的很冒火,想去找別的博主的程式碼借鑑一下,發現大部分,真的是大部分,
搜尋_BFS(廣度優先搜尋)_演算法分析
為方便討論BFS演算法, 考慮對圖的每個結點設定屬性color表示結點的顏色, color可取WHITE, GRAY, BLACK, 設定屬性d表示對應結點到源結點的最短路徑長度, 設定屬性p, 其中v.p表示存在一條從源結點到結點v的最短路徑且v的前驅為v.p, 下
C語言資料結構與演算法之深度、廣度優先搜尋
一、深度優先搜尋(Depth-First-Search 簡稱:DFS) 1.1 遍歷過程: (1)從圖中某個頂點v出發,訪問v。 (2)找出剛才第一個被頂點訪問的鄰接點。訪問該頂點。以這個頂點為新的頂點,重複此步驟,直到訪問過的頂點沒有未被訪問過的頂點為止。 (3)返回到
演算法----圖的遍歷(深度優先搜尋DFS、廣度優先搜尋BFS)
圖的遍歷的定義:從圖的某個頂點出發訪問圖中所有的點,且每個頂點僅被訪問一次。 深度優先搜尋DFS: 準備:指定的起始點和終點,確定好當前點與鄰接點之間的偏移值、結束搜尋的條件、符合訪問的點所需條件、回溯處理; (1)若當前點的鄰接點有未被訪問的,則選一個進行訪問; (2)若當前點的鄰接點都不符合訪問條
Go實現的廣度優先搜尋實現迷宮演算法
# 使用go實現的廣度優先搜尋實現迷宮演算法 package main import ( "errors" "fmt" "os" ) // 讀取檔案中的資料,使用迴圈生成迷宮圖 func readMazeFile(filename string) [][]int { f
廣度優先搜尋BFS(洛谷)
ACM題集:https://blog.csdn.net/weixin_39778570/article/details/83187443 深度優先搜尋DFS(洛谷) P1162 填塗顏色 題目:https://www.luogu.org/problemnew/show/P1162 題意:
二叉樹 深度優先搜尋(DFS)、廣度優先搜尋(BFS)
深度優先搜尋演算法(Depth First Search) DFS是搜尋演算法的一種。它沿著樹的深度遍歷樹的節點,儘可能深的搜尋樹的分支。 當節點v的所有邊都己被探尋過,搜尋將回溯到發現節點v的那條邊的起始節點。這一過程一直進行到已發現從源節點可達的所有節點為止。 如果還存在未被發現的節點,
廣度優先搜尋(BFS)----------------(TjuOj1140_Dungeon Master)
這次整理了一下廣度優先搜尋的框架,以後可以拿來直接用了。TjuOj1140是一個三維的迷宮題,在BFS時我增加了一個控制陣列,用來對佇列的出隊進行控制,確保每次出隊的結點均為同一步長的結點,個人認為比較適合這種迷宮搜尋題。 BFS部分的程式碼如下: int BFS ( node S , node T