[APCS] 20200704 程式實作題
這次 $APCS$ 的實作題,
難度約如下:
$P1$ | $P2$ | $P3$ | $P4$ |
★ | ★ | ★★★ | ★★★★★ |
$P3$ 看似簡單,
但爆力解只有 $20\%$ 的分數,
$P4$ 題敘很長,
需要的演算法也很難想。
題意:
第一行有兩個數 $a, \ b$,
代表兩個物品。
第二行有一個數 $T$,
代表以下有 $T$ 行資料。
每行資料輸入有多個數 $X_i$ (以 $0$ 結尾),
若 $X_i$ 為正數則放入購物籃,
反之則拿出購物籃。
判斷 $T$ 行中有多少行皆放入 $a, \ b$ 兩物品。
範圍:
$1 ≤ a, \ b, \ X_i ≤ 100, \ 1 ≤ T ≤ 100$。
範例輸入 $1.$:
1 8
5
1 8 0
5 6 0
2 7 0
8 1 0
33 22 0
範例輸出 $1.$:
2
程式碼參考:
C++:
#include <bits/stdc++.h>
#define _ ios::sync_with_stdio(false), cin.tie(nullptr);
#define endl '\n'
using namespace std;
int main() { _
int a, b, T, x, ans = 0;
cin >> a >> b >> T;
while (T--) {
map<int, int> mp;
while (cin >> x, x) {
if (x > 0)
mp[x] += 1;
else
mp[-x] -= 1;
}
if (mp[a] > 0 && mp[b] > 0)
ans += 1;
}
cout << ans << endl;
}
< $P2.$ 骰子 >
題意:
第一行有兩個數 $n, \ m$,
代表有 $n$ 個骰子和 $m$ 筆操作。
每個骰子上、下、左、右、前、後依序為 $1, \ 6, \ 5, \ 2, \ 4, \ 3$。
接著有 $m$ 行操作,
每行有兩個數 $a, \ b$,
其中 $1 ≤ a ≤ n, \ 1 ≤ b ≤ n$ 或 $b = -1$ 或 $b = -2$,
若 $b > 0$ 則 $a, \ b$ 兩顆骰子位置交換。
若 $b = -1$ 則骰子 $a$ 向前翻轉。
若 $b = -2$ 則骰子 $a$ 向右翻轉。
範圍:
$1 ≤ n ≤ 100, 1 ≤ m ≤ 100$。
範例輸入 1.:
1 2
1 -2
1 -1
範例輸出 1.:
3
範例輸入 2.:
3 3
2 -1
3 -2
3 1
範例輸出 2.:
5 3 1
程式碼參考:
C++:
#include <bits/stdc++.h>
#define _ ios::sync_with_stdio(false), cin.tie(nullptr);
#define endl '\n'
using namespace std;
struct s {
int up, down, left, right, front, back;
void ffn() {
// front_rotate function
// 向前翻轉
int tmp;
front = up, up = back, back = down, down = tmp;
}
void rfn() {
// right_rotate function
// 向右翻轉
int tmp;
up = left, left = down, down = right, right = tmp;
}
s(): up(1), down(6), left(5), right(2), front(4), back(3) {}
};
int main() { _
int n, m, a, b;
cin >> n >> m;
vector<s> v(n + 1);
while (m--) {
cin >> a >> b;
if (b > 0)
swap(v[a], v[b]);
else if (b == -1)
v[a].ffn();
else
v[a].rfn();
}
for (int i = 1; i <= n; i++)
cout << v[i].up << " \n"[i == n];
}
< $P3.$ 圓環迷宮 >
題意:
第一行有兩個數 $n, \ m$,
代表一個環狀迷宮有 $n$ 個房間(編號 $0, \ 1, \ 2, \ ..., \ n - 1)$,
接下來一行有 $n$ 個數,
代表著 $i$ 號房間有的點數 $P_i$。
接著一行有 $m$ 個數,
代表著第 $i$ 把鑰匙需要的點數 $Q_i$。
環狀迷宮走的順序為 $0, \ 1, \ 2, \ ..., \ n - 1, \ 0, \ 1, \ 2, \ ...$。
每次離開 $i$ 號房可以得到 $P_i$ 點數,
當點數達到 $Q_i$ 時即可兌換鑰匙(需要依序蒐集 $Q_0, \ Q_1, \ Q_2, \ ...$),
兌換時清會清空所有點數。
當蒐集完 $m$ 把鑰匙時,
試問準備進入哪一號房間。
範圍:
$1 ≤ n ≤ 2 × 10^5, 1 ≤ m ≤ 2 × 10^4$,
所有點數和不超過 $10^9$。
範例輸入 1.:
7 3
2 1 5 3 4 5 4
8 9 12
範例輸出 1.:
3
演算法:
- $Prefix \ Sum$(前綴和)。
- $Binary \ Search$(二分搜尋法)。
解題策略:
用前綴和記錄點數累積表,
再利用二分搜尋法找到該個點數,
直接跳到下個點數的編號。
< $P4.$ 病毒傳播 >
題意:
第一行有兩個數 $n, \ m$,
有 $n$ 條病毒長度為 $m$ 的 $RNA$。
接著有 $n$ 行,
每行有 $i, \ j, \ S_i$,
代表自身編號($1$ ~ $n$)、親代編號、$RNA$ 序列。
$RNA$ 序列中有 $A, \ U, \ C, \ G, \ @$,
$@$ 可為 $A, \ U, \ C, \ G$ 其中一個,
但每個 $RNA$ 序列的 $@$ 不一定要一樣。
差距定義為兩相鄰節點之基因序列不同位置數量,
試問所有的親代和子代最小的差距總和。
範例輸入 1.:
2 3
1 1 AAC
2 1 A@@
範例輸出 1.:
0
範例輸入 2.:
6 1
1 1 @
2 1 @
3 1 C
4 1 C
5 2 A
6 2 A
範例輸出 2.:
1
範圍:
$1 ≤ n ≤ 1000, 1 ≤ m ≤ 80$。
演算法:
- $DFS$(深度優先搜尋)。
- $DP$(動態規劃)。
以上,
若有更好的想法歡迎提出哦!
優秀欸GT
回覆刪除謝謝~還請多多支持:)
刪除