炸殭屍 bfs爆記憶體,dfs超時的問題

2021-10-12 21:07:44 字數 2754 閱讀 8254

1070: 炸殭屍

時間限制: 1 sec 記憶體限制: 128 mb

題目描述

媽媽得知小星星成功地解決了買玩具難題,獎勵他去看電影《生化危機 6》,小星星看著看著就替女主角擔心起來了,因為她要對付那麼多的殭屍怪物,小星星恨不得扔顆炸彈消除可惡的殭屍們,他腦袋裡開始構思出這樣的場景:

在乙個 n 行 m 列單元格構成的地圖中,去放置乙個炸彈,這種炸彈威力巨大,以放置點為中心進行行列延伸炸到同行同列的殭屍,但不能穿牆。上圖中可以把炸彈放置在第 3 行第 4 列,最多可以炸到 4 個殭屍,如果對地圖稍加改動(如下圖),在第 5 行第 4 列處加

入乙個牆體,又如何呢?答案還是最多炸到 4 個殭屍,只不過最佳炸彈放置點發生了變化,應該放到第 6 行第 6 列的位置。

當然炸彈要靠勇敢的小星星去放,他只能在地圖中朝上下左右四個方向行進(不能斜對

角移動),他不能穿牆,也不能穿越殭屍,要保證他的安全,如下圖,告訴你小星星起始位置是第 2 行第 2 列,那麼他的最佳放置炸彈位置應該是第 3 行第 2 列,最多炸到 2 個殭屍。

現在請聰明的你也一起加入到消除殭屍的隊伍來。

輸入第一行四個用空格隔開的正整數表示 n,m,x,y,分別表示 n 行 m 列的地圖,小星星起始位置第 x 行,第 y 列。

接下來 n 行 m 列用來描述地圖上每個單元格,『g』表示殭屍,『#』表示牆體,只有『.』

表示的單元格才是小星星能夠正常行走,能夠放置炸彈的單元格。(資料保證四面都是牆體,也就是第 1 行、第 n 行、第 1 列、第 m 列肯定都是牆體)。

輸出乙個整數,最多能炸掉的殭屍數量。

樣例輸入 copy

13 13 4 2

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

###…gg#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#

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

樣例輸出 copy

10提示

100%的資料,保證 n,m<2001, x蒟蒻博主這道題寫了兩天。大致記錄一下每一種思路。

1,(tle)先嘗試用bfs從起點開始走,之後每個點都計算所能炸到的殭屍數量,用時2900+ms,嚴重超時。

2,(tle&&mle)之後採用預處理,先用兩個雙重迴圈找出所有非牆的點能炸到的殭屍數量,存到乙個二維陣列中(ac**中依舊採用該預處理,但儲存方式不一樣),不僅多了50ms還把記憶體爆了。。

3,(tle&&mle)然後開始各種嘗試縮減記憶體,short int 都用上了,省的記憶體少的可憐。

4,(mle)bfs不行就嘗試dfs,依然保留預處理方式,用dfs遍歷並更新最大值,用時100+ms合格,但記憶體190k左右。。。

5,(ac)博主的bfs佇列用的是結構體存座標,結構體和二維陣列都存座標就造成了浪費,以至於爆記憶體,便採用線性表示儲存座標,也就是結構體的下標寫成x*maxn+y,遍歷改用灌水法,先將能到達的地方用bool vis二維陣列儲存節省空間 ,最後遍歷一次就可以了。

ac**:(37240kb 701ms)

#include

#include

using

namespace std;

typedef

short

int si;

//本題最大可能出現的數為4000,用short int 完全可以

const si maxn =

2001

;si ans,n,m;

si dx[4]

=,dy[4]

=;bool vis[maxn]

[maxn]

;struct node

s[maxn*

(maxn+1)

+1];

//線性表示座標,為方便處理,選擇1到n不是0到n-1讀入,這裡稍微擴大

node now,nt;

queueq;

void

bfs(si x,si y)

//廣搜

} q.

pop();

}}intmain()

si sum=0;

//下面是預處理,分橫向縱向兩次

//從左往右,碰到牆就結束該次炸到的殭屍數量統計

for(i =

1;i<=n;i++

)else

sum =0;

}}}//縱向同理

for(j =

1;j<=m;j++

)else

sum =0;

}}}bfs

(x,y)

;for

(i =

1;i<=n;i++)}

cout<

return0;

}

線性表示是看到學長在建立專案名時採用的編號112501(11月25日第1份**)學到的,在這道題上算是抖機靈吧,感謝支援。

過年回家炸金花

過年的時候和親戚朋友們一起炸金花,小贏了一把,仔細想想,我覺得炸金花的目的有三 1.娛樂,增進彼此間的感情 2.練 賭博 的氣概 3.建模 第一條很容易理解,而第二條,我是這樣理解的 人的一生會面臨種種抉擇,有時候沒能完全了解整個情況,可能只會根據目前的情況去推測事情的趨勢,勝負不明朗。這時候需要有...

日常(炸串會考)

這一周幾乎沒寫部落格,當然是因為學業水平考試啦 簡單吐槽一下吧 上午的數學 某老師 我敢說,最後一道選擇題一定是程式框圖 前兩年最後一道壓軸題都是函式,所以今年多半考解析幾何 於是乎 程式框圖變成了第十九題 最後一題是函式 均值不等式 某彥 我覺得我們不用學圓錐曲線了,因為某老師說高考最後一題一定是...

Swift 炸金花遊戲

1 豹子 同花順 同花 順子 對子 單張 2 處於一級別的兩手牌比較最大的一張牌的大小 3 若兩手牌為同一級別且最大的一張牌一樣,則比較剩下的牌 4.3張牌都相等後再從最大的牌比花色,但此機率實在太小,省略 設計思路 建立以下類 cards類 描述單張牌 play類 描述玩家 game類 控制遊戲流...