HDU 5094 題解(狀壓BFS)

2021-08-13 23:42:04 字數 2799 閱讀 7654

maze

題目中文大意:

這個故事發生在「星際迷航」的背景下。

「星際爭霸」的副隊長史波克落入克林貢的詭計中,被關押在他們的母親星球qo』nos上。

企業的上尉詹姆斯·t·柯克(james t. kirk)不得不乘宇宙飛船去救他的副手。幸運的是,他偷走了史波克所在的迷宮地圖。

迷宮是乙個矩形,它有n行垂直和m列水平,換句話說,它被分為n * m個位置。有序對(行號,列號)表示迷宮中的位置。柯克從當前位置移動到下乙個花費1秒。而且他只有在以下情況下才能移動到下乙個位置:

下乙個位置與當前柯克的位置相鄰(上下或左右)(4個方向)

開著的門是可以通行的,但鎖著的門不是。

柯克不能通過一堵牆

有幾種門是預設鎖定的。鑰匙只能開啟相同型別的門。柯克必須在開啟相應的門之前拿到鑰匙,這樣很浪費時間。

柯克的初始位置是(1,1),而史波克位於(n,m)的位置。你的任務是幫助kirk盡快找到史波克。

input

輸入包含很多測試樣例。

每個測試樣例由幾行組成。第一行中有三個整數,分別代表n,m和p (1<= n, m <=50, 0<= p <=10).

第二行只列出乙個整數k,表示門和牆的總數(0<= k <=500).

在下面的k行中有5個整數,表示 i1, y i1, x i2, y i2, g i; 當g i >=1,表示在位置 (x i1, y i1) 和 (x i2, y i2)之間存在型別gi的門;當g i = 0,說明 (x i1, y i1)和 (x i2, y i2),之間存在一堵牆 ( | x i1 - x i2 | + | y i1 - y i2 |=1, 0<= g i <=p )

下面的行是乙個整數s,表示迷宮中的鑰匙的總數。(0<= s <=50).

在下面的s行中有三個整數,分別表示x i1, y i1和q i這意味著型別為qi的鑰匙位於位置 i (x i1, y i1), (1<= q i<=p).

output

輸出kirk可能達到史波克的可能最小的秒數。

如果沒有可能的計畫,輸出-1。

sample input

4 4 9

9 1 2 1 3 2

1 2 2 2 0

2 1 2 2 0

2 1 3 1 0

2 3 3 3 0

2 4 3 4 1

3 2 3 3 0

3 3 4 3 0

4 3 4 4 0

2 2 1 2

4 2 1

sample output

14此題應使用廣度優先搜尋(bfs)

狀態壓縮:有10種鑰匙,那麼我們用10位二進位制來儲存鑰匙串(即乙個int整型變數),第i-1位是1表示有第i種鑰匙,為0則沒有鑰匙

用位運算來判斷是否能通過門(這些操作很常用,應牢記

將第i種鑰匙加入鑰匙串key

**:key|=(1<<(i-1))

例:key=0010 ,i=4,1<<(i-1)=1000,0010|1000=1010

拿著鑰匙串key,是否能通過第i種門

**:if(key&(1<<(i-1)==0) continue

例:(沒拿到第5種鑰匙,想通過第5種門)key=01101,i=5,1<<(i-1)=10000,00101|10000=0,通不過,continue

(拿到第4種鑰匙,想通過第4種門)key=01101,i=4,1<<(i-1)=01000,00101|10000=01000,可通過

#include

#include

#include

#define maxn 56

#define maxqu 50*50*(1<<11)+10

using

namespace

std;

int n,m,p,k,s;

struct node;

node now,nex;

node queue[maxqu];

int door[maxn][maxn][maxn][maxn];//鄰接矩陣存門

int keys[maxn][maxn];//二維陣列儲存每乙個點的鑰匙

int used[maxn][maxn][2055];//標誌是否走過

const

int walkx[4]=,walky[4]=;

int fread()

while(c>='0'&&c<='9')

return x*sign;

}bool judge(int x1,int y1,int x2,int y2)

int bfs()

if(keys[nex.x][nex.y]>0)

if(used[nex.x][nex.y][nex.key]==1) continue;

used[nex.x][nex.y][nex.key]=1;

tail++;

queue[tail].x=nex.x;

queue[tail].y=nex.y;

queue[tail].key=nex.key;

queue[tail].step=nex.step+1;}}

head++;

}while(head<=tail);

return -1;

}int main()

cin>>s;

for(int i=1;i<=s;i++)

cout

<}

}

hdu5094 狀態壓縮dp dps

題目大意 給定乙個棋盤,要求從 1,1 走到 n,m 相鄰格仔之前可能是牆,門或者什麼都沒有,牆的話就無法通過,門的話就必須有對應的鑰匙才能通過,要求求出最少的步數,若無法到達就輸出1。除錯了近兩個小時,一直找不到錯在哪,後來看了別人的程式,發現忘記考慮1 1的棋盤了。真是嗶了狗了。題很簡單,就是對...

HDU1429 勝利大逃亡 狀壓bfs

因為總共a j有10種鑰匙,所以可以把有沒有鑰匙的狀態壓到乙個int數里,然後dfs。昨天狀態特別不好寫超時了好幾次,但是這個題很簡單的,算是水題。1 include2 include3 include4 include5 include6 include7 using namespace std ...

狀壓dp題解

實現 includeconst int maxn 1 20 1 typedef long long ll ll f maxn a 25 a x 記錄第x行的障礙狀態 int lowbit int x int main f 0 1 乙個也不放也是一種方案 int maxs 1 判斷當前狀態下狀態的1的...