# 2023/06 APCS 實作題 # 第一題 - 路徑偵測 :::info https://zerojudge.tw/ShowProblem?problemid=k731 ::: ## 題目 給一個二維平面,座標如同數學的二維座 標(Y正為北,X正為東)。起始位置在 (0, 0),接下來會有 $n$ 個座標,你需要按照這些座標點的順序移動,保證僅會垂直 或水平方向上移動,不會斜向移動,且第 一個點保證一定是X軸正的位置(初始方向向右)。 請輸出這條路徑中,左轉、右轉、迴轉的 個數分別為多少。 子問題一 (60%) $n = 2$ 子問題二 (40%) $n \le 100$ ## 輸入說明: 第一行輸入一個正整數 $n$,接下來有 $n$ 行,每一行都有兩個正整數 $x$, $y$。保證的是相鄰兩個點的座標差值不超過 $100$。 ## 輸出說明: 輸出三個正整數,分別代表左轉、右轉、 迴轉的次數。 ## 解題絲路 這題很明顯是在考 **`在平面上的外積應用`**, 詳情可以參考 [內外積在程式中的應用](/zTX5_h5xQmeloZhV9WJjnQ) 所以我們知道正負號可判斷旋轉方向: * $> 0$ → 左轉 * $< 0$ → 右轉 * $= 0$ → 共線(迴轉或原地不動) 那這題就變簡單很多了,唯一要注意的是外積=0也可能是原地不動,要如何判斷是原地不動還是迴轉,要透過**內積**來判斷銳角還是鈍角 :::warning 兩向量夾角為鈍角($cos$鈍角<0)表示反方向 ::: ```cpp= #include <bits/stdc++.h> #define io ios::sync_with_stdio(0);cin.tie(0); using namespace std; struct Point { double x, y; }; int main() { io; int left = 0, right = 0, straight = 0; int n; cin >> n; Point p[105]; for (int i = 1; i <= n; ++i) cin >> p[i].x >> p[i].y; for (int i = 2; i <= n; ++i) { int x1 = p[i-1].x - p[i-2].x; // 向量 AB int y1 = p[i-1].y - p[i-2].y; int x2 = p[i].x - p[i-1].x; // 向量 BC int y2 = p[i].y - p[i-1].y; int dir = x1 * y2 - y1 * x2; // 外積 if (dir > 0) left++; else if (dir < 0) right++; else if (dir== 0 && (x1*x2<0||y1*y2<0))straight++; } cout << left << " " << right << " " << straight; } ``` # 第二題 - 特殊位置 :::info https://zerojudge.tw/ShowProblem?problemid=k732 ::: ## 題目 給定一個 $n \times m$ 的二維矩陣 a, 設 $x$ = a[i][j],離 $(i, j)$ 曼哈頓距 離為 $x$ 內的點數值總和 % 10 恰為 $x$ 的稱之為特殊位置。定義兩個點 (a, b) 和 (c, d) 的曼哈頓距離為 |a - c| + |b - d| 請寫一個程式,輸出共有幾個特殊位置, 並按照字典序由小到大輸出這些位置的座 標。 子問題一 (60%) $n = 1$ 子問題二 (40%) $n \le 50$, $m \le 50$ ## 輸入說明: 第一行輸入兩個正整數 $n, m (1 \le n, m \le 50)$,接下來有 $n$ 行,每行有 $m$ 個數字,每一個數字介於 $0$ 到 $9$ 。 ## 輸出說明: 第一行輸出共有幾個特殊位置,接下來輸 出 $k$ 行,每一行輸出兩個正整數代表作標點位。特殊位置請按照字典順序由小到 大輸出。 ## 解題絲路 題目講得蠻文言文的,我自己會這樣表述: > 對於每個位置 (i, j),令 x = a[i][j]。 > 計算所有與 (i, j) 曼哈頓距離<= x 的點的值總和 S。 > 若 S % 10 == x,則 (i, j) 為特殊位置。 透過迴圈去**模擬**每個元素的曼哈頓距離 ```cpp= #include <bits/stdc++.h> #define io ios::sync_with_stdio(0);cin.tie(0); using namespace std; int a[55][55]; vector<pair<int,int>> fans; int main() { io; int n,m; cin >> n >> m; for (int i=0;i<n;++i)for (int j=0;j<m;++j)cin >> a[i][j]; int ans=0; for (int i=0;i<n;++i){ for (int j=0;j<m;++j){ int x =a[i][j]; int cnt=0; for (int q=0;q<n;q++){ for (int p=0;p<m;p++){ if (abs(q-i)+abs(p-j)<=x) cnt += a[q][p];; } } if (cnt%10 == x){ ans++; fans.push_back({i, j}); } } } cout << ans << "\n"; for (auto [x, y] : fans) cout << x << " " << y << "\n"; } ``` --- :::info 趁機宣傳一下我自己的個人網站跟Youtube頻道 !! **[個人網站](https://hyc.eshachem.com/) | [Youtube頻道](https://www.youtube.com/@Hy.C)** ::: @2025 Hy.C 陳毓 > Copyright ©Hy.C 陳毓 CC BY-NC-SA 4.0 | 禁止商業用途 | 轉載標記出處 | 改 編作品必須在相同條款下分享。