摘要
這是我高一去參加APCS的經驗,和一個同班同學去考的,我跟他會去圖書館研究考古題,然後跟他一起去考。那時候還是舊制度,觀念用C語言、實作用Python。
觀念:80分(四級分)
實作:200/400(三級分)
| 題號 | 分數 |
|---|---|
| 1 | 100/100 |
| 2 | 100/100 |
| 3 | 0/100 |
| 4 | 0/100 |
😭 高一那時候對演算法不是很熟,只有寫基礎的兩題。
題解
P1 - 等紅綠燈
link >> https://zerojudge.tw/ShowProblem?problemid=q181
難度:APCS初?
題目敘述
操場起跑線上有一個紅綠燈,綠燈為秒,紅燈為秒,依照綠燈紅燈的順序循環。 有個小朋友,從操場的起跑線騎腳踏車一起起跑,他們分別騎完一圈的時間為。若騎到終點時為紅燈,需要等待紅燈結束變為綠燈才可以停止騎車。 求出這個小朋友共需要等待幾秒的紅燈秒數。
想法
cycle_time 決定完成一圈後所剩餘的循環秒數,如果不小於,代表當前為紅燈,就要將剩餘的紅燈等待時間加入到 total_time 中。
解答
1 | def solve(a, b, n, T): |
P2 - 字串操作
link >> https://zerojudge.tw/ShowProblem?problemid=q182
難度:APCS初?
題目敘述
給一個字串(長度為偶數),有三種字串操作,分別如下
-
- 兩兩交換:將字串內相鄰兩個字元交換,例如字串 “apcsntnu” 先分組成 (ap)(cs)(nt)(nu),將會交換為 (pa)(sc)(tn)(un),即得到 “pasctnun”。
-
- 兩兩排序:將字串內相鄰兩個字元按照字典序排序,字元的字典序為 a < b < … < z,例如字串 “family” 先分組成 (fa)(mi)(ly),將會交換成 (af)(im)(ly),即得到 “afimly”。
-
- 完美重排:假設字串長度為,將字串內的字元編號為,將字串分成兩半為和,並且組合成。例如"apcsntnu"拆成"apcs"和"ntnu",然後交錯成 “anptcnsu”。
想法
定義三個函式,代表三個操作,只要按照題目要求操作就好,沒有什麼好想的。
解答
1 | def op0(s): |
P3 - 重組問題
link >> https://zerojudge.tw/ShowProblem?problemid=q183
難度:APCS中高
從這一題開始後,都是我後來回來看的想法以及題解。
題目敘述
對於一個長度為的陣列,已知,定義為陣列中任兩個數字的絕對值差所組成的一群數字。給定的內容,輸出可以生成該的最小與最大字典序陣列。
舉例來說,如果且,距離最大的是,因為最大距離必定是在最小與最大兩數之間,我們可以推論原序列的最大的數字是。接著,目前已知原序列有,而距離序列扣除之後剩下,我們要決定中間點的位置。此時最大的距離是,這個距離必然是該未知點與「最小的0」或與「最大的7」之間的距離,所以這個點可能是或,在檢驗距離序列後,發現兩者皆可能,所以原序列可能是或,其中字典序最小的是,最大的是。
想法
因為那時候的我演算法基礎不佳,我在紙上一直寫,寫到最後也不太知道怎麼辦,最後就只能交出白卷了。
我們可以把一個序列分析他們兩兩之間的距離,距離所組成的序列就叫做。原序列中,最大的元素就是,而按照找到字典序小的方法就是依序找到數字最小的元素就好;反過來說,要找到字典序最大的方法就是找到數字元素最大的就好。
在字典序最小的序列中,我可以知道一定是,而且為了使最小,我一定要將剩下中最大的元素作為,就可以確保最小;而在字典序最大的序列中,一樣知道一定是,而且為了使最大,我一定要將剩下中最大的元素作為,就可以確保最大。而往後我們就依照這個邏輯枚舉,就可以找出原序列了!
我自己舉一個例子,接下來我們要透過窮舉、減枝、回溯就可以將所有可能的原序列找出來:

解答
1 | from collections import Counter |
P4 - 分組開會
link >> https://zerojudge.tw/ShowProblem?problemid=q184
難度:應該是現在的APCS高級
題目敘述
在人在一個數線上,他們的位置座標分別為。今天要從個人中挑的人開兩場會議,每一場會議要恰好個人參與,並且每一個人最多只能參與一個會議。若一個人位在,欲前往開會需要移動。請求出安排這兩場會議,使得參與會議的人移動距離總和最小值為何。