Try   HackMD

高一基礎程式設計免修上機考

前言

因為覺得免修很帥 所以就跑去考了一下
但越接近考試時 越來越緊張 :)

這篇主要是給那些學弟想考免修的一些參考ㄏㄏ

免修資格

  1. 要參加高一基礎程式設計的免修需要先有任課老師同意

    當初我與老師的談話

    老師 : 你來考免修是學過什麼嗎?
    我 : (腦袋想了一大堆演算法
    老師 : Python?
    我 : ㄜ我上學期上過C++的選修
    老師 :
    我 :
    (老師簽字)

    ps.反正老師一定會給你簽XD

  2. 送申請表到教務處的特教組 然後等上機考

  3. 上機考通過就免修了
    通過條件:五題對四題 也就是80/100 or 400/500

上機考情況

有5個人通過
然後有一個只差5分(幫QQ
Scoreboard

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

我是500/500的 不是沒上 放尊重一點ㄏㄚˋ

題目

pA

題意:

給你 24進制的

h小時
m
分鐘
s
秒 ex.(19:45:34)

h
m
s
為原點的24進位制時間 ( 類似格林威治天文臺

再給一個正負時區
l
(每一時區
1
hour
30
minutes
)

計算這個時區的36進制的時間為何
ps. 36進制為小時0~35分鐘、秒數皆60不變

通靈解題思路:

先將時區的多出或少掉的時間換算成 分鐘
然後再用取模的方式算

code:
  1. 數學解:)
#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"; }
  1. 暴力解
#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"; }

心得:

有點棘手的題目
考試當下我知道有數學解
但當時有點小緊張
所以沒那麼冷靜可以去思考
(暴力過就好XD

pB

題意:

給一原點

(x,y)
n
次操作 -> 給你方向
a
再給你移動距離
m

求最後的位置
(x,y)

a={1,2,3,4}
移動方向為
{
上,下,左,右
}

解題思路:

建表
不然就if開個4次 (反正時間很夠XD

code:

1.建表

#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

#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"; }

心得:

學過建表後code會比較簡潔 更容易修改

UPD: 忘記說了 這題範圍到2^31要開long long

pC

題意:

電梯 上樓時間

×3 下樓時間
×2

一開始在
1

搭了
n
次電梯 每次都有一個整數
a
代表去往樓層

求總共多少時間

解題思路:

if else 判上下樓 用一個常數維護上一樓

code:
#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"; }

心得:

水題

pD

題意:

有一個遙控器 可以轉台 目前在

a 台 想轉到
b

轉台機制 -> 如果目前頻道是奇數就
×3+1
不是就
÷2

請問要按幾次按鈕才能到b台

解題思路:

while迴圈

code:
#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"; }

心得:

一開始以為會TLE 結果水題ㄏㄏ
ps. 假如題目給定 a = 0 會TLE喔

  • pE
    UPD:

這題的原型應該是TOI2023新手題的第三題
連結: zero judge 398

題意:

n 個結帳台 每一個都有
A
個客戶且每個客戶都有
k
個商品

每結帳一個商品需要花
3
秒 除了第一個課戶以外 其他的客戶需要
2
秒的時間遞補上

請問第幾個結帳台所需的時間最小 且為多少秒

解題思路:

用for迴圈紀錄第幾的櫃檯
且用數學的角度看每個結帳櫃台需要的時間為

2×(a1)+Σ(3×ki) (所有商品總數x3)
最後維護一下答案

code:
#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"; }

心得:

相較之下有水準的題目
但第一題比較需要想 所以這題還是秒解