玩轉深度優先搜尋演算法

2021-09-02 16:07:58 字數 3294 閱讀 5042

小時候玩遊戲,有個bomb人的遊戲,把bomb放在乙個空地上,將怪獸炸死,如圖:

bomb的威力只要不碰到牆壁,可以無限延長。那麼我們應該把bomb放**可以炸死最多的怪獸呢?

這個問題貌似很簡單,乙個乙個地方試下不就知道了嗎?是啊,那我們用**來試下。

將圖象轉成字元,用#表示牆,用g表示怪獸,用.表示空地,最後得到的字元為:

#############

#gg.ggg#ggg.#

###.#g#g#g#g#

#.......#..g#

#g#.###.#g#g#

#gg.ggg.#.gg#

#g#.#g#.#.#.#

##g...g.....#

#g#.#g###.#g#

#...g#ggg.gg#

#g#.#g#g#.#g#

#gg.ggg#g.gg#

#############

那我只要把所有的空地試下就知道**放bomb最好了。

int main()

for (i = 0; i <= n - 1; i++)

//當前可以炸0個怪獸

sum = 0;

x = i;

y = j;

//向上擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

x = i;

y = j;

//向下擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

x = i;

y = j;

//向左擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

x = i;

y = j;

//向右擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

//如果消滅的怪獸大於map,則更新map,並記住所在的座標

if(sum > map)}}

printf("將bomb放在(%d,%d)處,可以消滅最多%d怪獸只\n", p, q, map);

getchar();

getchar();

return 0;

}

列印結果為:將bomb放在(1,11)處,可以消滅最多11怪獸只。這種演算法為列舉,

好像有點不對勁啊,小人根本到不了(1,11),所以那裡根本不放了bomb。所以說我們不能將所有的空地都計算進去,需要將到不了的空地排除。這裡該深度優先演算法出場了(當然還有其它演算法可以解決)。

走過迷宮的都知道,我們會沿一條走到頭,死路時就回頭,回到上乙個岔路口,已經確定了一條死路,我們就走另一條路,又是死路,我們就再回到岔路口,兩條都是死路了,就回到上上個岔路口,依此迴圈。

這個問題就像小人在走迷宮,直到所有的空地都被小人走過為此。我們用遞迴來實現這個邏輯:

char a[20][21];

int book[20][20];//標記某個點是否被走過

int max, mx, my, n, m;

//計算當前空地可以炸死的怪獸

int getsum(int i, int j)

x = i;

y = j;

//向下擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

x = i;

y = j;

//向左擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

x = i;

y = j;

//向右擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

return sum;

}void dfs(int x, int y)

, , , };

int k, sum, tx, ty;

sum = getsum(x, y);

if(sum > max)

for(k = 0; k <= 3; k++)

}return ;

}int main()

book[startx][starty] = 1;

mx = startx;

my = starty;

max = getsum(startx, starty);

dfs(startx, starty);

printf("將bomb放置在(%d,%d),最多可以消滅%d個怪獸\n", mx, my, max );

return 0;

}

得到結果:將bomb放置在(7,11),最多可以消滅10個怪獸。

我再用「棧」來實現:

char a[20][21];

//棧的節點

struct note

;//獲取當前空地能消滅的怪獸數

int getsum(int i, int j)

x = i;

y = j;

//向下擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

x = i;

y = j;

//向左擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

x = i;

y = j;

//向右擴充套件計算消滅的怪獸數

while(a[x][y] != '#')

return sum;

}int main()

book[startx][starty] = 1;

mx = startx;

my = starty;

//當起始點加入到棧中

top++;

que[top].x = startx;

que[top].y = starty;

max = getsum(startx, starty);

int next[4][2] = , , , };

int k, sum, tx, ty;

//直到棧空了

while(top != 0)

for(k = 0; k <= 3; k++)

//這句很關鍵,乙個空地上下左右都試走過後,將此空地移除棧

if(k == 3)top--;}}

printf("將bomb放置在(%d,%d),最多可以消滅%d個怪獸\n", mx, my, max );

return 0;

}

得到的結果是一樣的。

這套演算法應用十分廣泛,可以解決很多問題。作為一名碼農還是非常有必要學習一下的,與這對應的還有「廣度優先搜尋演算法」.

深度優先搜尋演算法

include include define vertexnum 9 struct node typedef struct node graph struct node head vertexnum 定義圖形結構 int visited vertexnum 頂點陣列 深度優先搜尋 void dfs ...

深度優先搜尋演算法

今天我們來複習一下萬能的搜尋演算法之深度優先搜尋演算法。深度優先搜尋演算法顧名思義就是按照樹的延伸不停的往下搜尋,直到樹的盡頭之後再一步一步的回溯回來。好吧,我們直接問你乙個問題,給你乙個數n,讓你輸出從1到這個樹的全排列,你會怎麼寫,會不會想到去用若干個for迴圈?好吧,你肯定錯了,其實他考的就是...

深度優先搜尋演算法

1.深度優先搜尋演算法的概念 深度優先搜尋屬於圖演算法的一種,英文縮寫為dfs depth first search.其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個 節點只能訪問一次。如下例 該圖為乙個無向圖,假設我們從a開始進行深度優先搜尋,第二點可以是b c d中任意乙個,...