← 10/29|vector 與運算子重載入門(Ch 7) | 回總覽 | 11/12|運算子重載、friend 與 string(Ch 8、Ch 9) →
期中考是上機考,也是多數人第一次在考場上寫程式。這篇給你三樣東西:考前一週的複習清單、考場流程、一份可以計時做完的五題模擬考與完整解答。(這是主課的期中考;實驗課沒有期中考,它自己的上機考在期末,題型見文末。)
範圍到 Ch6 的 class 基礎為止:
1 | 基本語法 → 流程控制 → 函式與參數傳遞 → 陣列(含二維) → struct / class(存取控制、setter/getter、const 成員函式) |
不包含建構子、vector、運算子重載——課綱寫的期中範圍就是 Ch1–Ch6,而這三樣屬於 Ch7 之後,所以 10/22、10/29 這兩週留到期末。現在不用複習它們,但別忘了期末全考。
考前一週的複習清單
老師說過期中考幾乎全部從課本勾選的習題出(總覽頁那張表的「課本指定習題」欄,Ch1–Ch6),所以第一件事是把那些題目每一題自己寫過一遍(每篇文章開頭的〈這幾題各要用到什麼〉表列出每題需要的東西與對應練習)。接著下面每一項都要做到不看筆記能寫出來(括號是對應的模擬考題號):
- ☐ 格式化輸出:
fixed << setprecision(n)控小數位(→ Q1、Q4、Q5)、setw(n)控欄寬(→ Q4)、setfill('0')補零(模擬考沒出,自己拿 Q4 多加一欄練) - ☐ 函式三件事:回傳
bool的判斷函式(→ Q2)、用double&一次帶回兩個結果(→ Q1)、同名函式重載三個版本(模擬考沒出,自己補一題) - ☐ 一維陣列:讀入與累加(→ Q1)、找最大值與索引、手寫排序(→ Q4)、反轉(模擬考沒出,自己補一題)
- ☐ 二維陣列:讀入、印出、轉置、每列每行求和(→ Q3)
- ☐
struct:定義、陣列、傳進函式、整包交換(→ Q4) - ☐
class:private 資料 + public setter +const成員函式(→ Q5)、getter(自己補) - ☐ 默寫〈環境設置〉那份模組化 Makefile(助教範本的形式:變數+每題兩行),
make clean && make通過且零警告(不用自己發明,背熟就好)
+=、i++、單獨一行的 cout << fixed << setprecision(2);——這三個寫法忘了就回 09/17 翻。另外主課的期中題目通常會先給你數量 n,用 for 讀就好;「讀到結束值才停」的寫法是實驗課考題的習慣,見下面第二份模擬考。
上機考當天的流程
- 開場三分鐘先搭架子,不要一上來就衝第一題:(這裡的
1
2mkdir B1130xxxxx && cd B1130xxxxx
nano Makefile # 貼上默背好的模組化 Makefile&&是 shell 的「前一個指令成功才做下一個」,跟 C++ 的邏輯&&沒有關係。)之後每題只是新增Qn.cpp,make一下全部編好。 - 先掃過五題,從最有把握的開始,不要卡在第一題。
- 每寫完一題就
make並跑題目給的範例,警告當場清掉。 - 剩 15 分鐘停止寫新功能,改成
make clean && make確認乾淨重編沒問題。 - 打包後找助教確認:
1
2
3make clean # 重編確認過了才打包,zip 裡只留原始碼(.cpp、.h)和 Makefile
cd ..
zip -r B1130xxxxx.zip B1130xxxxx/
完整繳交規則見〈環境設置〉。兩條會要命的:Makefile 編不過 = 0 分、有任何警告或錯誤扣 2 分。
模擬上機考(建議計時 90 分鐘)
正式期中考依 1151 學期課程資料是 90 分鐘五題(實際題數與時間以當學期公告為準),這份模擬考照同樣的量設計。時間是總量參考、不是順序(順序照上面第 2 步,從最有把握的開始):Q2、Q5 各 10 分鐘,Q1、Q3 各 15 分鐘,Q4 最久 25 分鐘,留 15 分鐘機動與重編打包。
解答裡有不少 for 沒加大括號——跟 09/17 講 if 時同一條規則:for、while 後面也只管一個敘述,而那個敘述可以是一行程式,也可以是另一個 for(Q3 的兩層迴圈就是這樣)。決定範圍的是語法不是縮排,自己寫還是建議一律加。
Q1. 平均與標準差
讀入 n(1 ≤ n ≤ 1000)與 n 個整數,輸出平均與母體標準差,各保留兩位小數。計算的部分要寫成獨立函式,用兩個 double& 參數把平均與標準差一起帶回 main。
$$\mu = \frac{1}{n}\sum x_i, \qquad \sigma = \sqrt{\frac{1}{n}\sum (x_i - \mu)^2} $$
1 | 輸入: |
Q2. 完全數
讀入 n,輸出 1 到 n 之間所有的完全數(除了自己以外的因數總和等於自己,例如 6 = 1+2+3)。請把「判斷是否為完全數」寫成獨立函式。
1 | 輸入: 500 |
Q3. 矩陣的行列總和與轉置
讀入 n、m(都不超過 100)與矩陣,輸出每一列的和、每一行的和,最後印出這個矩陣的轉置。
1 | 輸入: |
Q4. 圖書資料
定義 struct Book { string title; string author; int year; double price; };,讀入 n 本書(n ≤ 1000),每行一本:書名 作者 年份 價格,其中書名與作者都保證是不含空白的單字(含空白的字串要等 Ch9 學會 getline 才處理得了)。輸出:
- 價格最高的書名
- 依出版年由舊到新排序後的完整清單,由
void printBook(const Book& b)負責輸出,每行印「年份 書名 作者 價格」四欄:年份在行首直接印、不補寬,其餘三欄分別是setw(12)、setw(10)、setw(8)
1 | 輸入: |
Q5. 矩形類別
寫 class Rectangle,private 資料為寬高,提供 setter(負數視為 0)、area()、perimeter()、isSquare(),全部唯讀函式都要加 const。讀入寬高後印出三個結果,面積與周長保留兩位小數。
1 | 輸入: 3 4 |
Q1 參考解答
1 |
|
考點與常見扣分:母體標準差的分母是 n 不是 n - 1;忘了 fixed 的話 3.8 會印成 3.8 而不是 3.80,格式不符就算錯。陣列大小照題目的上限開(這題是 1000),開太小會寫爆陣列——可能當場 *** stack smashing detected *** 或 Segmentation fault,也可能一聲不響地把別的變數改壞(10/08〈雷區①〉的三種症狀),偏偏編譯器完全不會擋你;題目寫明 n ≤ 10000 就開 10000。題目沒給上限就舉手問助教——猜一個「看起來夠大」的數字不是解法,固定大小的陣列本來就裝不下未知數量的資料,真正的解是 10/29 的 vector。
Q2 參考解答
1 |
|
考點與常見扣分:題目明講「寫成獨立函式」,寫在 main 裡就不合規格。邊界是 1(不是完全數,所以 n < 2 直接回 false)。first 旗標只是為了讓數字之間有空白、行尾沒有多餘空白。
進階:因數成雙成對出現(找到 2 就同時知道 6 / 2 = 3),所以有一種只掃到
i * i <= n的寫法快很多,但要另外處理i = 1(配出來的n / 1是n自己)與平方數(那一對是同一個因數)兩個特例。n ≤ 500用不到——上機考先求對,別急著優化。
Q3 參考解答
1 |
|
考點與常見扣分:陣列大小必須是編譯時就確定的常數,所以用 const int MAX,不能是 int n; cin >> n; int a[n]; 這種執行時才知道的值(10/08〈雷區②〉);寫在 main 裡或 main 外都合法,放外面只是多個函式共用比較方便。二維陣列別開太大——放在 main 裡的陣列全部加起來大約只有幾 MB 可用,int a[2000][2000](約 16 MB)一跑就 Segmentation fault;100 × 100 這種題目夠用。分隔空白這裡用了兩種寫法:row sums: 前面已經有標籤,所以每個數字前都印一格;transpose 每行開頭不能有空白,改成「第一個不印、之後才印」——Q2 的 first 旗標是同一招。
Q4 參考解答
1 |
|
考點與常見扣分:Book t = b[j]; 是整包交換,不要四個欄位各換一次(漏一個就整筆錯位)。setw 只影響下一個輸出,所以三欄各寫一次;年份在行首、不需要補寬。
Q5 參考解答
1 |
|
考點與常見扣分:唯讀的成員函式一律加 const,漏掉必扣分。isSquare() 直接用 == 比兩個 double 在這題是安全的,因為 w、h 直接來自輸入、沒經過任何運算;一旦值是算出來的(例如 w * 3 / 3),就要改成 fabs(w - h) < 1e-9(fabs 在 <cmath>、1e-9 的科學記號寫法 10/29 講過),意思是「差距小到可以當作相等」。這題刻意不寫建構子(期中不考),但 10/22 已經學過了,考完之後自己寫類別請一律補上,否則物件一建立、setter 還沒呼叫之前就是垃圾值。
實驗課上機考題型(Ch 1–6 的部分)
實驗課是另一門課,有自己的期末上機考(佔實驗課成績 40%),題型就是每週練習題那種。我看過的幾份歷年考古題有幾個共同特徵:連續輸入、讀到 0 或 0 0 結束、輸出格式要一模一樣、一題只有全對或零分。下面六題裡,Q1、Q3、Q4、Q5 的題型取自那些考古題(題目敘述、範例資料與解答是我重寫的,不是原題),Q2、Q6 是我照同樣風格自己出的;六題只用 Ch 1–6 的內容,期中前就可以練;主課的期中考不是這種題型(幾乎全從課本勾選題出),別搞混。六題建議 90 分鐘。
實驗課考題有個習慣要先適應:多半不給你數量 n,而是「一直讀到某個結束值」,所以大部分題目的骨架都是 while (true) { cin >> ...; if (結束條件) break; ... }。
Q1. 沙漏
反覆讀入整數 N,N 是正奇數時印出高 N 列的沙漏(第一列 N 顆星、每列少兩顆到 1 顆、再加回 N 顆),否則印 invalid;讀到 0 結束。星號前面要補空白讓圖形置中,星號後面不印空白。
1 | 輸入: |
Q2. 質數原地降冪
反覆讀入一串正整數(以 0 結尾,最多 1024 個),把其中是質數的那些由大到小重新排列,其他數字的位置不動;讀到空的一串(直接輸入 0)就印 done 結束。
1 | 輸入: |
Q3. 區間內的質數
反覆讀入 x y,印出 x 到 y 之間(含)所有質數,同一行用空白隔開;x > y 或有負數印 invalid range;區間內沒有質數就不印任何東西(連換行都不印);讀到 0 0 結束。
1 | 輸入: |
Q4. 爬樓梯
一次可以爬 1 階或 2 階,問爬到第 n 階有幾種走法(0 < n < 45,其他值印 invalid)。反覆讀入直到 0。
1 | 輸入: |
Q5. 狀態機計算器
先讀 n,再讀 n 個整數。程式有五個狀態輪流切換:第 1 個數進入 SET(直接記下來);之後依序 PLUS(結果 + 輸入)、MINUS(結果 − 輸入)、TIMES(結果 × 輸入)、OVER(輸入 ÷ 結果,整數除法);OVER 之後回到 PLUS 循環。OVER 時若結果是 0,印 [OVER] cannot divide by 0, reset,下一個數重新從 SET 開始。每一步印 [狀態] 結果。
1 | 輸入: |
1 | 輸入: |
Q6. 成績結構排序
struct Student 存五科分數與總分。讀入 n 個學生(每行五個整數),分數不在 0–100 的視為 0,依總分由高到低印出每人的五科與總分。
1 | 輸入: |
Q1 參考解答
1 |
|
考點與常見扣分:每列的空白數是 (N - 星數) / 2;下半部從 3 顆開始(1 顆那列已經在上半部印過)。N = 1 只有一列,兩個迴圈剛好一個印一個不印,不需要特判。行尾多印空白就是零分,-Wall 抓不到這種錯,要自己拿題目範例對。
Q2 參考解答
1 |
|
考點與常見扣分:排序骨架還是選擇排序,只是「參與排序的位置」加了條件——i 不是質數就跳過,找最大值時也只看質數。這樣非質數自然留在原地。第二組資料只有一個質數 3、第三組一個都沒有,所以印出來跟原本一樣。每一串讀完要把 n 歸零,這是連續輸入題最常忘的一行。
Q3 參考解答
1 |
|
考點與常見扣分:三個判斷的順序——先檢查結束、再檢查不合法、最後才算;「沒有質數就不印」包含不印換行,所以用 any 旗標決定要不要 '\n'。isPrime 直接沿用 09/24 那份。
Q4 參考解答
1 |
|
考點與常見扣分:走到第 n 階的最後一步不是 1 階就是 2 階,所以 ways(n) = ways(n-1) + ways(n-2)——就是費氏數列,用 09/24 Q6 的迴圈寫法。n = 44 的答案超過 11 億,int 剛好還裝得下,但再大一點就不行,直接用 long long 最保險。
Q5 參考解答
1 |
|
考點與常見扣分:OVER 是「輸入除以結果」,方向跟前面三個相反;除以零那一筆不算一步,狀態直接回 SET,所以要 continue 跳過 state 的推進。switch 裡每個 case 都有 break,除以零那條用 continue 離開的是外面的 for——continue 跳的是迴圈、不是 switch。
Q6 參考解答
1 |
|
考點與常見扣分:總分要在讀入時順便算好存進結構,排序時才不用一直重算;交換的是整個 Student。這題實驗課的正式版本會讓每行分數「可能缺少幾科」,要用 getline + stringstream 一行一行拆,那是 12/03 的內容,期中不會考。
對完答案之後
五題全對、make 零警告,期中就穩了。哪一題寫不出來,回去補對應的那一篇:
- Q1 → 10/01 參數傳遞:
double&一次帶回多個結果 - Q2 → 09/24 流程控制與函式:迴圈、
%、自訂函式 - Q3 → 10/08 陣列:二維陣列
- Q4 → 同上(手寫排序)+ 10/15 struct 與 class:struct 傳參與整包交換
- Q5 → 10/15 struct 與 class:存取控制、
const成員函式
← 10/29|vector 與運算子重載入門(Ch 7) | 回總覽 | 11/12|運算子重載、friend 與 string(Ch 8、Ch 9) →
說些什麼吧!