# 2023/10 APCS 實作題 # 第一題 - 機械鼠 :::info https://zerojudge.tw/ShowProblem?problemid=m370 ::: ## 題目 有 $n$ 個位置上有食物,另外有一隻老鼠一開始位於位置 $x$。 老鼠在開始覓食前要選擇今天要往左邊或 往右移動去尋找食物,經過食物時可以停 下來吃食物,吃完後可以選擇繼續往相同 方向移動,或者是結束今天的覓食。 請問老鼠最多能吃到多少個食物,以及最 後停下來吃食物的位置。 ## 輸入說明: 第一行包含兩個整數:$x$ 和 $n$,以空 格分隔。$x$ 代表老鼠的初始位置,$n$ 代表食物的數量。 第二行包含 $n$ 個整數,以空格分隔,表示每個食物的位置,且不會與老鼠位置重 疊。 所有測試資料皆保證 $3 \leq n \leq 20$ 且 $n$ 是奇數,老鼠與食物位置範圍均 為 $-100$ 到 $100$。 子題分數: 60%:滿足 $n = 3$。 40%:一般情況。 ## 輸出說明: 請輸出兩個整數,分別代表最多能吃到的 食物數目和最後一個吃的食物停下的位置 。 ## 解題絲路 排序後去比較: 1. 0~x比較多還是 2. x~n比較多 ```cpp= #include <bits/stdc++.h> #define io ios::sync_with_stdio(0);cin.tie(0); using namespace std; int main(){io; int x,n; cin >> x >> n; vector<int> li(n+1); for (int i=0;i<n;++i)cin >> li[i]; li[n] = x; sort(li.begin(),li.end()); auto it = find(li.begin(), li.end(), x); int idx = distance(li.begin(),it); int mx = max((n-idx),(idx)); cout << mx << " "; if (mx == idx)cout << li[0]; else cout << li[li.size()-1]; } ``` # 第二題 - 卡牌遊戲 :::info https://zerojudge.tw/ShowProblem?problemid=m371 ::: ## 題目 你有一個 $n \times m$ 大小的表格,你 可以從中消除具有相同數值且之間沒有障 礙物的兩個元素,並獲得分數。請問你可 以獲得的最大得分。 每一種數字在表格中出現恰好兩次。消除 兩個相同的數字 $x$ 時,可以獲得 $x$ 分。 消除規則:你可以垂直或水平地將兩個相 同數值的元素消除,但消除的兩個元素之 間不能有其他尚未消除的元素。 ## 輸入說明: 第一行包含兩個整數:$n$ 和 $m$,以空 格分隔。它們分別代表表格的行數和列數 。 接下來有 $n$ 行,每行包含 $m$ 個整數 ,以空格分隔,表示表格中的元素。每個 元素的數值範圍介於 $[0, 1000]$ 之內,且每種數字在表格中出現恰好兩次。 輸入保證表格上的每種數字恰好出現兩次 ,且表格的格數為偶數。 子題分數: 60%:滿足 $n = 1, 1 \leq m \leq 40$。 40%:滿足 $1 \leq n \leq 20, 1 \leq m \leq 40$。 ## 輸出說明: 請輸出一個整數,代表你可以獲得的最大 得分。 ## 解題絲路 用迴圈去遍歷每個元素,走到該元素時判斷兩件事: 1. 右邊元素是否相同 2. 下面元素是否相同 如果相同,就加上分數後,將兩個元素都改成1001 **之後遇到1001就穿越他** 迴圈停止條件為: **直到找不到相鄰的兩元素** => 適合用while迴圈。 設一布林值,如果該布林值在此次迴圈未被修改,表示已經沒有可以消去的相鄰元素了。 ```cpp= #include <bits/stdc++.h> #define io ios::sync_with_stdio(0);cin.tie(0); using namespace std; int graph[25][45] = {}; int main() { io int n, m; cin >> n >> m; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> graph[i][j]; } } int cnt = 0; bool changed = true; while (changed) { changed = false; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (graph[i][j] == 1001) continue; int tmpi = i + 1, tmpj = j + 1; while (tmpi < n && graph[tmpi][j] == 1001) tmpi++; if (tmpi < n && graph[i][j] == graph[tmpi][j]) { cnt += graph[i][j]; graph[i][j] = graph[tmpi][j] = 1001; changed = true; } while (tmpj < m && graph[i][tmpj] == 1001) tmpj++; if (tmpj < m && graph[i][j] == graph[i][tmpj]) { cnt += graph[i][j]; graph[i][j] = graph[i][tmpj] = 1001; changed = true; } } } if (!changed) break; } cout << cnt; } ``` :::info 這種解法稱為: 模擬 就是一步步去拓展並求解。 ::: --- :::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 | 禁止商業用途 | 轉載標記出處 | 改 編作品必須在相同條款下分享。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up