# **APCS Sep 2021 - g276 [Q2](https://zerojudge.tw/ShowProblem?problemid=g276) [Python]** > **本題敘述:** > >在一個 n x m 的棋盤上有 k 個魔王,一開始第 i 個魔王位於 (r_i, c_i) 的位置上,並且每回合會移動 (s_i, t_i)。也就是說,若本來在 (x, y) 位置,經過移動後會跳到 (x + s_i, y + t_i) 位置。 > > 每個魔王都有不同的 r_i, c_i, s_i, t_i 值,每回合每個魔王移動前會在位置放下一顆炸彈,然後才進行移動,而若魔王移動到炸彈的位置,炸彈則會引爆。魔王移動和炸彈消失不見。如果兩個魔王同時踏到同一個炸彈上會一起引爆。如果同一位置有多個炸彈也會被一起引爆。 > 當魔王移動超出整個棋盤的範圍,則視為消失。 > > 請計算,當棋盤上沒有任何魔王時,盤面上總共剩下幾格有炸彈? ```python= n, m, k = map(int, input().split()) the_list = [[0 for _ in range(m)] for _ in range(n)] boss = [] for _ in range(k): r, c, s, t = map(int, input().split()) boss.append([r, c, s, t]) while boss: boom = set() to_remove = [] for i in range(len(boss)): r, c = boss[i][0], boss[i][1] if the_list[r][c] == 0: # 只有位置為0才要增加 the_list[r][c] = 1 for i in range(len(boss) - 1, -1, -1): # range(起始值, 結束值(不會碰到), 增量) r, c, s, t = boss[i] new_r, new_c = r + s, c + t if new_r >= n or new_c >= m or new_r < 0 or new_c < 0: # 確認是否超出邊界 to_remove.append(i) continue if the_list[new_r][new_c] > 0: if (new_r, new_c) not in boom: boom.add((new_r, new_c)) to_remove.append(i) else: boss[i][0], boss[i][1] = new_r, new_c for i in sorted(to_remove, reverse=True): # 確保不會影響要移除的boss順序 boss.pop(i) for (r, c) in boom: the_list[r][c] = 0 # 計算剩餘的炸彈數量 total = 0 for row in the_list: total += sum(row) print(total) ``` --- **解題報告:** 題目動作說明: 1. **輸入數據**: - 讀取 `n`, `m`, `k`,以及每個魔王的初始位置和移動向量。 2. **初始化棋盤**: - 創建一個大小為 `n x m` 的棋盤 `the_list`,初始值為 0,表示沒有炸彈。 3. **模擬每回合魔王的行為**: - 每回合每個魔王在當前位置放置一顆炸彈。 - 所有魔王移動到下一個位置(同時)。 - 如果移動到邊界外,魔王消失。 - 如果移動到已有炸彈的位置,炸彈引爆(此區炸彈為0),並移除該魔王。 4. **計算剩餘炸彈數量**: - 當所有魔王都消失後,迴圈 `the_list` 並計算所有剩餘炸彈的數量。 ### 本題重點: 1. **第一個 `for` 迴圈要用倒序**: - 當你在列表中要使用`i`刪除元素時,如果從頭到尾按正序迴圈並刪除元素,會導致列表長度變化,影響後續元素的索引。例如: ```python lst = [1, 2, 3, 4, 5] for i in range(len(lst)): if lst[i] % 2 == 0: lst.pop(i) ``` 在第一次迴圈中,`lst[1]` 被刪除,此時列表變為 `[1, 3, 4, 5]`,但是索引 `i` 會繼續增加,導致下一個偶數 `4` 被跳過。 - 而倒序迴圈確保當刪除元素時,不會影響尚未迴圈的元素的索引。例如: ```python lst = [1, 2, 3, 4, 5] for i in range(len(lst) - 1, -1, -1): if lst[i] % 2 == 0: lst.pop(i) ``` 這樣,每次刪除元素時,後面的元素已經被迴圈,不會受到影響。 **本題知識:** * **模擬** * **列表操作** * **集合** --- - [✔️] 程式碼如果需要可以直接使用。 - [✔️] 分享貼文請標註來源。 - [✔️] 呃呃...這次有點慢。 ![image](https://hackmd.io/_uploads/H1uMOgfNC.png)