[APCS] 20200704 程式實作題


這次 APCS 的實作題,
難度約如下:
P1 P2 P3 P4
★★★ ★★★★★
P1, P2 十分簡單,
P3 看似簡單,
但爆力解只有 20% 的分數,
P4 題敘很長,
需要的演算法也很難想。


< P1. 購物分析 >
題意:
第一行有兩個數 a, b
代表兩個物品。
第二行有一個數 T
代表以下有 T 行資料。
每行資料輸入有多個數 Xi (以 0 結尾),
Xi 為正數則放入購物籃,
反之則拿出購物籃。
判斷 T 行中有多少行皆放入 a, b 兩物品。

範圍:
1a, b, Xi100, 1T100

範例輸入 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
其中 1an, 1bnb=1b=2
b>0a, b 兩顆骰子位置交換。
b=1 則骰子 a 向前翻轉。
b=2 則骰子 a 向右翻轉。

範圍:
1n100,1m100

範例輸入 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, ..., n1)
接下來一行有 n 個數,
代表著 i 號房間有的點數 Pi
接著一行有 m 個數,
代表著第 i 把鑰匙需要的點數 Qi
環狀迷宮走的順序為 0, 1, 2, ..., n1, 0, 1, 2, ...
每次離開 i 號房可以得到 Pi 點數,
當點數達到 Qi 時即可兌換鑰匙(需要依序蒐集 Q0, Q1, Q2, ...),
兌換時清會清空所有點數。
當蒐集完 m 把鑰匙時,
試問準備進入哪一號房間。

範圍:
1n2×105,1m2×104
所有點數和不超過 109

範例輸入 1.:
7 3
2 1 5 3 4 5 4
8 9 12
範例輸出 1.:
3

演算法:
  • Prefix Sum(前綴和)。
  • Binary Search(二分搜尋法)。
解題策略:
用前綴和記錄點數累積表,
再利用二分搜尋法找到該個點數,
直接跳到下個點數的編號。


< P4. 病毒傳播 >
題意:
第一行有兩個數 n, m
n 條病毒長度為 mRNA
接著有 n 行,
每行有 i, j, Si
代表自身編號(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

範圍:
1n1000,1m80

演算法:
  • DFS(深度優先搜尋)。
  • DP(動態規劃)。


以上,
若有更好的想法歡迎提出哦!

留言

張貼留言

熱門文章