狀態壓縮 廣度優先搜尋 迷宮遊戲

2021-09-05 09:50:43 字數 2470 閱讀 7582

【題目描述】

pluto 已經很久沒有玩遊戲了,今天 pluto 難得能夠歇一天。於是,pluto 決定要玩乙個非常好玩的迷宮遊戲。這個迷宮遊戲在乙個 n 行 m 列的矩陣上進行,遊戲中的任意時刻不能走出這個矩陣。在這個矩陣中,有下列幾種元素:

. :表示一塊平地。

x :表示一堵牆,不能經過。

s :表示遊戲的起點,有且僅有乙個。

t :表示遊戲的終點,有且僅有乙個。

a~h :表示一種型別的門,每種型別的門最多隻會出現一次。

a~h :表示每種型別的門對應的鑰匙,每種型別的鑰匙最多隻會出現一次,並且保證只會與對應型別的門同時出現。

在這個遊戲中,玩家從起點開始,每次向上下左右中的乙個方向移動一格,若發生下列任意一種或多種情形,則該步移動不合法,遊戲退出。

1 . 走出矩陣。

2 . 移動後的格仔中是牆。

3 . 移動後的格仔中是門,且還未獲得對應的鑰匙。

若玩家走到乙個有鑰匙的格仔中,則玩家將獲得格仔中的鑰匙(注意:玩家不能選擇放棄獲取。)最終,若玩家到達終點,則遊戲完成。

現在,pluto 希望你能幫助他在完成遊戲的同時,獲得盡量少的鑰匙。如果有多解,請輸出任意一解。

【輸出描述】

一共若干字元,表示你的操作序列。『u』表示向上,『d』表示向下,『l』表示向 左,『r』表示向右。(注意:輸出的操作序列需保證長度不超過 10000000。

【樣例輸入】

3 4s.a.

.x.x

atx.

【樣例輸出】

rrllddr

狀態壓縮常用於不好表示狀態的dp和類似這道題的搜尋,一般特點是題目中某一維度資料規模較小。狀態壓縮基於二進位制的位運算,利用二進位制中的0和1來表示狀態。一般常用兩種位運算:

|(按位或運算):對於兩個數a,b,二進位制表示法a,b中的每一位上有1則為1,否則為零。

eg.a=101001010;

b=001000110;

c=101001110;(c=a|b)

&(按位與運算):對於兩個數a,b,二進位制表示法a,b中的每一位,都是1則為1,否則為0。

eg.a=101001010;

b=001000110;

c=001000010;(c=a&b)

基於以上操作,我們可以用乙個int來儲存當前鑰匙有無的狀態。1表示有,0表示無,從低位到高位依次表示鑰匙a,鑰匙b,鑰匙c…那麼我們可以利用位運算來實現判斷鑰匙和新增鑰匙。同時,由於同乙個格仔可能重複走,每次經過鑰匙狀態不同,因此我們需要乙個三維的vis陣列來當做廣度優先搜尋的判重陣列,前兩位表示座標,第三維表示鑰匙狀態,因此我們就能得到如下演算法:

#include

#include

#include

#include

#include

#include

#include

#define re register

using

namespace std;

int n,m;

int dx[4]

=;int dy[4]

=;char mp[

201]

[201];

struct nodek,u;

int a,b;

bool vis[

201]

[201][

129]

;struct ndepre[

201]

[201][

129]

;//記錄當前狀態由哪乙個格仔轉移過來,便於列印方案。

int sx,sy;

inline

void

pree

(node &u)

//找到終點和起點

int yy;

inline

bool

check

(node &k,

int&i)

//方案合法判斷

if(mp[k.x]

[k.y]

=='t')if

(mp[k.x]

[k.y]

=='.'

)else

else}}

return0;

}char ans[

50001];

inline

void

print

(int x,

int y,

int s)

for(

int i=cnt;i>

0;i--

)putchar

(ans[i]);

}inline

void

bfs(

)for

(int re i=

0;i<

4;i++);

}}}int

main()

是不是超級友好的一道題?然而我除錯了乙個小時。

迷宮 BFS 廣度優先搜尋

小c最近在研究機械人,他想看看自己的機械人夠不夠智慧型,於是他將機械人放在乙個n m的迷宮中,看看機械人能不能在最短的時間內到達目的地,可是小c不知道最短的時間是多少,現在請你幫他算算機械人到達目的地的最短時間是多少?輸入描述 輸入資料第一行兩個整數n和m。n和m的範圍 10,500 接下來n行,每...

迷宮問題(廣度優先搜尋BFS

給定乙個迷宮,入口為左上角,出口為右下角,問是否有路徑從入口到出口,若有則輸出一條這樣的路徑。注意移動可以從上 下 左 右 上左 上右 下左 下右八個方向進行。迷宮輸入0表示可走,輸入1表示牆。易得可以用1將迷宮圍起來避免邊界問題。本題採用bfs演算法給出解。注意,利用bfs演算法給出的路徑必然是一...

廣度優先搜尋(迷宮問題2)

s01e 0010 0010 0100 0000 s010 0000 0010 01e0 0000 s011 0011 1111 1111 111e include include typedef struct node node int main node s m n turn m n memse...