這題有兩個做法,一個是直接生成一個二維陣列模擬迷宮的狀態,另一個是不模擬迷宮,僅記錄炸彈與魔王的座標;
第一個作法在解題報告中有很多人用了,這邊我使用的是第二個做法。
先說明一些條件:
我們的目標是當魔王全部淘汰時,計算「有幾格有炸彈」,所以每一格裡面有幾個炸彈並不重要,我們不在乎;只需要知道那一格「有沒有」炸彈即可。
換句話說,對於每個格子的狀態,就只需要紀錄 True
有炸彈和 False
沒炸彈兩種。
解題方法:
讀資料時,使用二維陣列紀錄每一位魔王的資料 boss_info
= [[r1, c1, s1, t1], [r2, c2, s2, t2], ......]
使用一個空集合 bomb
紀錄座標位置,因為我們不需要在意有幾顆炸彈,我們只在意有沒有炸彈。
你也可以不使用集合,而是用 list 紀錄,但考慮到地雷可能有 100 x 100 = 10000 這麼多,用集合效率會更好一些。
每次循環時,需要檢查是否還有 BOSS 存活,如果 BOSS 全死了,那就退出循環,由於我們不知道最後會循環幾次,所以這邊使用 while
循環更合適。
在每次循環中,要做三件事: 魔王下炸彈,魔王移動,魔王死掉。
可以直接遍歷一次 boss_info
,先把每個魔王的當前座標添加到 bomb
中,表示魔王移動前放下炸彈的位置;然後根據題目指示直接移動魔王的位置。
注意,這個階段我們不需要在意炸彈的狀態,魔王該做什麼就做什麼。
接下來來需要再重新遍歷一次 boss_info
,在這個階段中,我們要判斷魔王們移動後是否還能存活,以及有哪些格子的炸彈需要被清除。
判斷魔王是某能存活的邏輯很簡單,踩到炸彈或跑出範圍就是淘汰,主要麻煩在清除炸彈的部分需要另外做,因為魔王是「同時」移動的,但我們的程式只能一個一個檢查。
可以創建一個 temp
集合,用來記錄需要被移除的炸彈,在遍歷的過程中只要發現有魔王踩到炸彈,就把炸彈的座標紀錄到 temp
裡面。
在循環的最後面,就直接讓集合做差集運算,把應該移除的炸彈從 bomb
刪除,直接寫成 bomb - temp
就可以了,python 就是這麼簡單。
最後,當沒有魔王存活、退出循環時,只需要輸出 len(bomb)
就是答案了
可能有人會疑惑為什麼我們要在一個循環遍歷兩次 boss_info
,而非一次搞定。其實上面有提到,但還是再強調一下理由,因為魔王是「同時」移動的,但我們的程式只能一個一個檢查魔王的狀態,如果都塞在同一個循環內完成,那魔王們就不是「同時」移動,而是依序移動了。
參考答案: gist 連結