1. 程式人生 > >推箱子尋求最少步數(廣度優先搜尋)

推箱子尋求最少步數(廣度優先搜尋)

“推箱子”這個經典的遊戲,具體規則就是在一個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