---
# System prepended metadata

title: APCS實作題2025年10月中級第1題：彗星撞擊
tags: [C++, APCS, Python]

---

# APCS實作題2025年10月中級第1題：彗星撞擊

> 日期：2025年11月2日
> 作者：王一哲
> [ZeroJudge 題目連結](https://zerojudge.tw/ShowProblem?problemid=r488)

<br />

## 解題想法

用二維陣列儲存地圖每格的高度，用字典儲存恐龍所在的位置及數量。每次讀取到撞擊位置、範圍及深度之後，先用一次雙層 for 迴圈掃過範圍內的格子，檢查是否有清醒的恐龍，如果有的話則更新清醒恐龍的數量、將字典中對應的數量歸零；如果沒有清醒的恐龍，再跑一次雙層 for 迴圈，更新範圍內的格子高度。處理完 M 次撞擊之後，再掃過地圖一次，找出最高、最低高度。
<br /><br />

## Python 程式碼

使用時間約為 10 ms，記憶體約為 3.2 MB，通過測試。
```python=
R, C, D = map(int, input().split())  # 地圖 R*C，初始高度 D
grid = [[D]*C for _ in range(R)]  # 用二維串列儲存地圖及高度
K = int(input())  # K 隻清醒的恐龍
dinosaurs = dict()  # 座標: 數量
for _ in range(K):  # 讀取 K 行資料
    r, c = map(int, input().split())
    if (r, c) not in dinosaurs:
        dinosaurs[r, c] = 1
    else:
        dinosaurs[r, c] += 1
M = int(input())  # M 次撞擊
for _ in range(M):  # 讀取 M 行資料
    a, b, s, d = map(int, input().split())  # 撞擊位置 (a, b)，範圍 s，深度 d
    have_dinosaurs = False  # 範圍內是否有清醒的恐龍
    for r in range(a - s//2, a + s//2 + 1, 1):  # 掃過撞擊範圍內的格子
        for c in range(b - s//2, b + s//2 + 1, 1):
            if 0 <= r < R and 0 <= c < C:  # 如果沒有出界
                if (r, c) in dinosaurs and dinosaurs[r, c] > 0:  # 如果 (r, c) 位置有清醒的恐龍
                    K -= dinosaurs[r, c]  # K 減去這個位置的恐龍數量
                    dinosaurs[r, c] = 0  # 歸零
                    have_dinosaurs = True  # 範圍內有清醒的恐龍
    if not have_dinosaurs:  # 範圍內沒有清醒的恐龍
        for r in range(a - s//2, a + s//2 + 1, 1):  # 掃過撞擊範圍內的格子
            for c in range(b - s//2, b + s//2 + 1, 1):
                if 0 <= r < R and 0 <= c < C:  # 如果沒有出界
                    grid[r][c] -= d  # 高度減去 d
# 輸出答案
imax, imin = 0, D  # 最大高度、最低高度
for r in range(R):
    imax = max(imax, *grid[r])
    imin = min(imin, *grid[r])
print(f"{imax:d} {imin:d} {K:d}")
```
<br />

## C++ 程式碼

使用時間約為 2 ms，記憶體約為 792 kB，通過測試。
```cpp=
#include <cstdio>
#include <vector>
#include <map>
#include <utility>
#include <algorithm>
using namespace std;

int main() {
    int R, C, D;  // 地圖 R*C，初始高度 D
    scanf("%d %d %d", &R, &C, &D);
    vector<vector<int>> grid (R, vector<int> (C, D));  // 用二維陣列儲存地圖及高度
    int K; scanf("%d", &K);  // K 隻清醒的恐龍
    map<pair<int, int>, int> dinosaurs;  // 座標: 數量
    for(int i=0; i<K; i++) {  // 讀取 K 行資料
        int r, c; scanf("%d %d", &r, &c);
        dinosaurs[make_pair(r, c)]++;
    }
    int M; scanf("%d", &M);  // M 次撞擊
    for(int i=0; i<M; i++) {  // 讀取 M 行資料
        int a, b, s, d;  // 撞擊位置 (a, b)，範圍 s，深度 d
        scanf("%d %d %d %d", &a, &b, &s, &d);
        bool have_dinosaurs = false;  // 範圍內是否有清醒的恐龍
        for(int r = a - s/2; r <= a + s/2; r++) {  // 掃過撞擊範圍內的格子
            for(int c = b - s/2; c <= b + s/2; c++) {
                if (r >= 0 && r < R && c >= 0 && c < C) {  // 如果沒有出界
                    pair<int, int> pos = make_pair(r, c);
                    if (dinosaurs[pos] > 0) {  // 如果 (r, c) 位置有清醒的恐龍
                        K -= dinosaurs[pos];  // K 減去這個位置的恐龍數量
                        dinosaurs[pos] = 0;  // 歸零
                        have_dinosaurs = true;  // 範圍內有清醒的恐龍
                    }
                }
            }
        }
        if (!have_dinosaurs) {  // 範圍內沒有清醒的恐龍
            for(int r = a - s/2; r <= a + s/2; r++) {  // 掃過撞擊範圍內的格子
                for(int c = b - s/2; c <= b + s/2; c++) {
                    if (r >= 0 && r < R && c >= 0 && c < C) {  // 如果沒有出界
                        grid[r][c] -= d;  // 高度減去 d
                    }
                }
            }
        }
    }
    // 輸出答案
    int imax = 0, imin = D;  // 最大高度、最低高度
    for(int r=0; r<R; r++) {
        for(int c=0; c<C; c++) {
            imax = max(imax, grid[r][c]);
            imin = min(imin, grid[r][c]);
        }
    }
    printf("%d %d %d\n", imax, imin, K);
    return 0;
}
```
<br /><br />

---

###### tags:`APCS`、`C++`、`Python`

