小時候玩遊戲,有個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()列印結果為:將bomb放在(1,11)處,可以消滅最多11怪獸只。這種演算法為列舉,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;
}
好像有點不對勁啊,小人根本到不了(1,11),所以那裡根本不放了bomb。所以說我們不能將所有的空地都計算進去,需要將到不了的空地排除。這裡該深度優先演算法出場了(當然還有其它演算法可以解決)。
走過迷宮的都知道,我們會沿一條走到頭,死路時就回頭,回到上乙個岔路口,已經確定了一條死路,我們就走另一條路,又是死路,我們就再回到岔路口,兩條都是死路了,就回到上上個岔路口,依此迴圈。
這個問題就像小人在走迷宮,直到所有的空地都被小人走過為此。我們用遞迴來實現這個邏輯:
char a[20][21];得到結果:將bomb放置在(7,11),最多可以消滅10個怪獸。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;
}
我再用「棧」來實現:
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中任意乙個,...