# 高一基礎程式設計免修上機考 ## 前言 因為覺得免修很帥 所以就跑去考了一下 但越接近考試時 越來越緊張 :) ==**這篇主要是給那些學弟想考免修的一些參考ㄏㄏ**== ## 免修資格 1. 要參加高一基礎程式設計的免修需要先有任課老師同意 :::spoiler 當初我與老師的談話 老師 : 你來考免修是學過什麼嗎? 我 : ...(腦袋想了一大堆演算法 老師 : Python? 我 : ㄜ...我上學期上過C++的選修 老師 : ... 我 : ... (老師簽字) ps.反正老師一定會給你簽XD ::: 2. 送申請表到教務處的特教組 然後等上機考 3. 上機考通過就免修了 通過條件:五題對四題 也就是==80/100== or ==400/500==分 ## 上機考情況 有5個人通過 然後有一個只差5分(幫QQ [Scoreboard](http://skyoj.tnfsh.tn.edu.tw/sky/index.php/contest/scoreboard/555) ![免修](https://hackmd.io/_uploads/BJo9gZIap.png) 我是==500/500==的 不是沒上 放尊重一點ㄏㄚˋ ## 題目 ### **pA** **題意:** :::success **給你 24進制的 $h$小時 $m$分鐘 $s$秒 ex.(19\:45\:34)** **$h$ $m$ $s$ 為原點的<font color="red">24進位制</font>時間 ( 類似格林威治天文臺** **再給一個正負時區 $l$ (每一時區$1$ $hour$ $30$ $minutes$)** **計算這個時區的<font color="red">36進制</font>的時間為何** **ps. 36進制為小時0~35分鐘、秒數皆60不變** ::: **~~通靈~~解題思路:** :::warning **先將時區的多出或少掉的時間換算成 分鐘** **然後再用取模的方式算** ::: :::spoiler **code:** 1. **數學解:)** ```cpp= #include <iostream> #include <iomanip> // setw & setfill using namespace std; int main() { int h, m, s, l; cin >> h >> m >> s >> l; int now = l*3*30; // 每一個l有60min + 30min m += now%60; // 將m + now取一小時後剩下的餘數 = min if(m >= 60) { // 如果時區是正數 m -= 60; h++; } if(m < 0) { // 如果時區是負數 m = (m+60)%60; h--; } h = ((h+now/60)%36+36)%36; // 將h + now除上60分鐘 = hour //偷渡個 setw cout << h << ":" << setw(2) << setfill('0') << m << ":" << setw(2) << setfill('0') << s << "\n"; } ``` 2. **暴力解** ```cpp= #include <iostream> #include <iomanip> // setw & setfill using namespace std; int main() { int h, m, s, l; cin >> h >> m >> s >> l; if(l > 0) { // 正時區 h += l*1 + l/2; h %= 36; m += l%2*30; if(m >= 60) {h++; m -= 60;} } else { // 負時區 for(int i = 0; i < abs(l); i++) { if(m < 30) { m += 30; h--; } else { m-= 30; } h--; if(h < 0) {h+=36;} } } //偷渡個 setw cout << h << ":" << setw(2) << setfill('0') << m << ":" << setw(2) << setfill('0') << s << "\n"; } ``` ::: **心得:** :::danger **有點棘手的題目** **考試當下我知道有數學解** **但當時有點小緊張** **所以沒那麼冷靜可以去思考** **(暴力過就好XD** ::: ### **pB** **題意:** :::success **給一原點$(x,y)$ $n$次操作 -> 給你方向$a$ 再給你移動距離$m$** **求最後的位置 $(x',y')$** $a=\{1,2,3,4\}$**時** **移動方向為**$\{$上,下,左,右$\}$ ::: **解題思路:** :::warning **建表** **不然就if開個4次 (反正時間很夠XD** ::: :::spoiler **code:** **1.建表** ```cpp= #include <iostream> using namespace std; int dx[] = {0, 0, -1, 1}; int dy[] = {1, -1, 0, 0}; int main() { int x, y; cin >> x >> y; int n; cin >> n; for(int i = 0; i < n; i++) { int a, m; cin >> a >> m; x += dx[a-1]*m; // 記得a 是1~4但陣列是從0~3 y += dy[a-1]*m; } cout << "(" << x << "," << y << ")\n"; } ``` **2.if else 或 switch** ```cpp= #include <iostream> using namespace std; int main() { int x, y; cin >> x >> y; int n; cin >> n; while(n--) { int a, m; cin >> a >> m; if(a == 1) { x += m; } else if(a == 2) { x -= m; } else if(a == 3) { y -= m; } else { y += m; } // or // switch(a) { // case 1: // // 懶得寫 // break; // // 2 , 3, 4 // } } cout << "(" << x << "," << y << ")\n"; } ``` ::: **心得:** :::danger **學過建表後code會比較簡潔 更容易修改** ::: **UPD:** **忘記說了 這題範圍到2^31要開<font color = "red" >long long </font>** ### **pC** **題意:** :::success **電梯 上樓時間 $\times3$ 下樓時間 $\times2$** **一開始在 $1$ 樓** **搭了$n$次電梯 每次都有一個整數$a$代表去往樓層** **求總共多少時間** ::: **解題思路:** :::warning **if else 判上下樓 用一個常數維護上一樓** ::: :::spoiler **code:** ```cpp= #include <iostream> using namespace std; int main() { int n; cin >> n; int last = 1; // 一開始在一樓 int ans = 0; // 求多少時間 for(int i = 0; i < n;i++) { int a; cin >> a; if(a-last <0) { // 下樓 ans += (last-a)*2; } else { // 上樓 ans += (a-last)*3; } last = a; } cout << ans << "\n"; } ``` ::: **心得:** :::danger **水題** ::: ### **pD** **題意:** :::success **有一個遙控器 可以轉台 目前在 $a$ 台 想轉到 $b$ 台** **轉台機制 -> 如果目前頻道是奇數就 $\times 3 +1$ 不是就 $\div2$** **請問要按幾次按鈕才能到b台** ::: **解題思路:** :::warning **while迴圈** ::: :::spoiler **code:** ```cpp= #include <iostream> using namespace std; int main() { int a, b; cin >> a >> b; ll ans = 0; while(a != b) { ans++; if(a&1) { a = a*3 + 1; } else { a/=2; } } cout << ans << "\n"; } ``` ::: **心得:** :::success **一開始以為會TLE 結果水題ㄏㄏ** **ps. 假如題目給定 a = 0 會TLE喔** ::: * **pE** **UPD:** :::danger **這題的原型應該是TOI2023新手題的第三題** **連結**: [zero judge 398](https://zerojudge.tw/ShowProblem?problemid=m398) ::: **題意:** :::success **有 $n$ 個結帳台 每一個都有 $A$ 個客戶且每個客戶都有 $k$ 個商品** **每結帳一個商品需要花 $3$ 秒 除了第一個課戶以外 其他的客戶需要 $2$ 秒的時間遞補上** **請問第幾個結帳台所需的時間最小 且為多少秒** ::: **解題思路:** :::warning **用for迴圈紀錄第幾的櫃檯** **且用數學的角度看每個結帳櫃台需要的時間為 $2\times(a-1) + \Sigma (3\times k_i)$ (所有商品總數x3)** **最後維護一下答案** ::: :::spoiler **code:** ```cpp= #include <iostream> #include <climits> //INT_MAX using namespace std; int main() { int n; cin >> n; int mn = INT_MAX, id = -1; for(int i = 0; i < n; i++) { int a; cin >> a; int ans = 2*(a-1); for(int i = 0; i < a; i++) { int k; cin >> k; ans += k*3; } if(ans < mn) { mn = ans; id = i; } } cout << id+1 << " " << mn << "\n"; } ``` ::: **心得:** :::danger **相較之下有水準的題目** ~~**但第一題比較需要想 所以這題還是秒解**~~ :::