資料結構與演算法 搜尋 一 廣度優先搜尋

2021-09-10 16:29:06 字數 4043 閱讀 2203

首先需要說明,這裡所說的廣度優先搜尋,與利用廣度優先搜尋對圖進行遍歷有一定的差別。廣度優先搜尋確實可以以被應用在圖的遍歷當中,但其應用遠不僅如此。我們通過乙個例題,引出廣度優先搜尋:

例:勝利大逃亡

題目描述:

ignatius被魔王抓走了,有一天魔王出差去了,這可是ignatius逃亡的好機會,魔王住在乙個城堡裡,城堡是乙個a * b * c 的立方體,可以被表示成a個b * c 的矩陣,剛開始ignatius被關在(0,0,0)的位置,離開城堡的門在(a-1,b-1,c-1)的位置,現在知道魔王將在t分鐘後回到城堡,ignatius每分鐘能從乙個座標走到相鄰的六個座標中的其中乙個。現在給你城堡的地圖,請你計算出ignatius能否在魔王回來前離開城堡(只要走到出口就算離開城堡,如果走到出口的時候魔王剛好回來也算逃亡成功),如果可以請輸出需要多少分鐘才能離開,如果不能則輸出-1。

輸入:輸入資料的第一行是乙個正整數k,表明測試資料的數量。每組測試資料的第一行是四個正整數a,b,c和t(1<=a,b,c<=50,1 <= t <= 1000),它們分別代表城堡的大小和魔王回來的時間,然後是a塊輸入資料(先是第0塊,然後是第1塊,第2塊……),每塊輸入資料有b行,每行有c個正整數,代表迷宮的布局,其中0代表路,1代表牆。

輸出:對於每組測試資料,如果ignatius能夠在魔王回來前離開城堡,那麼請輸出他最少需要多少分鐘,否則輸出-1.

樣例輸入:

133

42001

1100

1101

1111

1110

0101

1100

0001

1001

10

樣例輸出:
11
**如下:

#include

#include

#include

using namespace std;

bool mark[50]

[50][

50];// 標記陣列

int maze[50]

[50][

50];// 儲存立方體資訊

struct n

;queue q;

// 佇列,佇列中的元素為狀態

int go[

3]=;

intbfs

(int a,

int b,

int c)

}return-1

;// 若所有的狀態被查詢完後,仍得不到所需座標,則返回-1

}int

main()

}}while

(q.empty()

== false) q.

pop();

// 清空佇列

mark[0]

[0][

0]= true;

// 標記起點

n tmp;

tmp.t = tmp.y = tmp.x = tmp.z =0;

// 初始狀態

q.push

(tmp)

;// 將初始狀態放入佇列

int rec =

bfs(a,b,c)

;// 廣度優先搜尋

if(rec <= t)

printf

("%d\n"

,rec)

;// 若所需時間符合條件,則輸出

else

printf

("-1\n");

// 否則輸出-1

}return0;

}

執行結果:

例:非常可樂

題目描述:

大家一定覺得運動以後喝可樂是一件很愜意的事情,但是seeyou卻不這麼認為。因為每次當seeyou買了可樂以後,阿牛就要求和seeyou一起分享這一瓶可樂,而且一定要喝得和seeyou一樣多。但seeyou的手中只有兩個杯子,它們的容量分別是n毫公升和m毫公升,可樂的體積為s(s < 101)毫公升(正好裝滿一瓶),它們三個之間可以互相倒可樂(都是沒有刻意的,且s == n + m,101>s>0,n>0,m>0)。聰明的acmer你們說他們能平分嗎?如果能請輸出倒可樂的最少次數,如果不能輸出"no"

輸入:三個整數:s 可樂的體積,n和m是兩個杯子的容量,以"0 0 0"結束。

輸出:如果能平分的話請輸出最少要倒的次數,否則輸出"no"。

樣例輸入:

743

4130

00

樣例輸出:
no

3

**如下:

#include

#include

#include

using namespace std;

struct n

;queue q;

// 佇列

bool mark[

101]

[101][

101]

;// 對體積組(x,y,z)進行標記,即只有第一次得到包含體積組(x,y,z)的狀態為有效狀態,其餘的捨去

void

atob

(int

&a,int sa,

int&b,

int sb)

else

}int

bfs(

int s,

int n,

int m)

a = now.a;

b = now.b;

c = now.c;

// 重置a,b,c為未傾倒前的體積

atob

(b,n,a,s)

;// 由b傾倒向a

if(mark[a]

[b][c]

== false)

a = now.a;

b = now.b;

c = now.c;

atob

(a,s,c,m)

;// 由a傾倒向c

if(mark[a]

[b][c]

== false)

a = now.a;

b = now.b;

c = now.c;

atob

(c,m,a,s)

;// 由c傾倒向a

if(mark[a]

[b][c]

== false)

a = now.a;

b = now.b;

c = now.c;

atob

(b,n,c,m)

;// 由b傾倒向c

if(mark[a]

[b][c]

== false)

a = now.a;

b = now.b;

c = now.c;

atob

(c,m,b,n)

;// 由c傾倒向b

if(mark[a]

[b][c]

== false)

}return-1

;}intmain()

for(

int i =

0; i <= s ; i++)}

}// 初始化狀態

n tmp;

tmp.a = s;

tmp.b =0;

tmp.c =0;

tmp.t =0;

while

(q.empty()

== false) q.

pop();

// 清空佇列中的狀態

q.push

(tmp)

;// 將初始狀態放入佇列

mark[s][0

][0]

= true;

// 標記初始狀態

int rec =

bfs(s,n,m)

;// 廣度優先搜尋

if(rec ==-1

)puts

("no");

else

printf

("%d\n"

,rec);}

return0;

}

執行結果:

資料結構與演算法 廣度優先搜尋1

廣度優先搜尋演算法 先查詢離起始頂點最近的,然後是第二進的,這樣依次往外搜尋。樹的層次遍歷就是乙個廣度搜尋演算法。一般需要用到佇列這個資料結構,但是如果你是c語言開發,並且是在考試中,時間有限。一般臨時寫乙個佇列出來還是很耗時間的,所以一般用乙個大陣列來模擬佇列。今天做了兩道力扣題目,總結一下bfs...

資料結構 廣度優先搜尋

實驗任務 眾所周知,索隆是乙個路痴,一天在一小島上,他又迷路了!好 山治心急如焚,決定出去找他,由於練成了月步,山治的速度竟然達到了正無窮!小島上除了空地,還有盤 絲洞 簡稱 psd 盤絲洞裡住著可愛的妹紙,山治每次經過乙個盤絲洞,都要停留乙個單 位時間來欣賞妹紙,給你乙個 n m 的地圖以及山治和...

廣度優先搜尋 資料結構

廣度優先搜尋 bfs 的乙個常見應用是找出從根結點到目標結點的最短路徑。結點的處理順序是越是接近根結點的結點將越早地遍歷。佇列的入隊和出隊順序是新新增的節點不會立即遍歷,而是在下一輪中處理。結點的處理順序與它們新增到佇列的順序是完全相同的順序,即先進先出 fifo 這就是我們在 bfs 中使用佇列的...