109 年 國立政治大學數位內容碩士學位學程創意傳播組《計算機概論與程式設計》

📄 試題原卷 免費註冊後即可對照原始考卷 PDF免費註冊

第 1 題

  1. Which of the following object is not for storing data?
    (A) ROM
    (B) Register
    (C) SSD
    (D) Cache
    (E) None

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查電腦中不同儲存元件的功能。判斷重點是:只要元件能夠在某段時間內保存資訊,就具有儲存資料的功能;保存時間長短不影響其「儲存」的本質。

  • ROM:非揮發性記憶體,可保存韌體或固定程式。
  • Register:CPU 內部的暫存器,用於保存運算中的資料、位址或控制資訊。
  • SSD:非揮發性儲存裝置,可長期保存檔案與程式。
  • Cache:高速快取記憶體,用於暫時保存常用資料與指令。

解題方法

逐一判斷各元件是否具有「保存資料或資訊」的功能。即使某元件只能短暫保存資料,只要資料在處理期間被保留,仍屬於資料儲存。

選項分析

(A) ROM

ROM 是 Read-Only Memory 的縮寫,屬於非揮發性記憶體。即使電源關閉,通常仍能保留其中的資料,常用來存放開機韌體。因此 ROM 是用來儲存資料的元件,選項錯誤。

(B) Register

🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 2 題

  1. Which of the following number is larger than 76 in decimal?
    (A) 10110100 in 2's complement
    (B) 1000100 in binary
    (C) 4A in Hexadecimal
    (D) 116 in Octal
    (E) None

登入後即可作答並保存紀錄。

這一題的完整詳解

本題要求將不同進制表示的數字轉換為十進制,並比較大小,找出大於 76 的數字。

首先,我們將每個選項的數字轉換為十進制:

(A) 1011010010110100 in 2's complement:
這個數字有 8 位元。最高位是 1,表示為負數。
計算其二補數的絕對值:

  1. 反轉位元:0100101101001011
  2. 加 1:01001011+1=0100110001001011 + 1 = 01001100
    將二進制 0100110001001100 轉換為十進制:
    0×27+1×26+0×25+0×24+1×23+1×22+0×21+0×200 \times 2^7 + 1 \times 2^6 + 0 \times 2^5 + 0 \times 2^4 + 1 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 0 \times 2^0
    =64+0+0+8+4+0+0=76= 64 + 0 + 0 + 8 + 4 + 0 + 0 = 76
    所以,原來的二補數 1011010010110100 代表十進制的 −76-76。
    −76-76 小於 7676。
🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 3 題

  1. Which of the following expression is True if A: True, B: False and C: False?
    (A) (A AND B) OR C
    (B) (A NAND B) XOR C
    (C) (A NOR B) XOR C
    (D) (A XOR (NOT B)) OR C
    (E) A AND (B OR C)

登入後即可作答並保存紀錄。

這一題的完整詳解

本題考驗邏輯運算符的理解與應用,給定 A, B, C 的布林值,需要計算出各個邏輯表達式的結果。
A = True (T)
B = False (F)
C = False (F)

我們逐一計算各選項:

(A) (A AND B) OR C
(T AND F) OR F
F OR F
F (False)

(B) (A NAND B) XOR C
(T NAND F) XOR F
NAND 的結果是 NOT (AND),所以 T NAND F = NOT (T AND F) = NOT (F) = T
T XOR F
T (True)

🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 4 題

  1. Which of the following sorting method has the smallest worst time complexity in Big-O?
    (A) Merge sort
    (B) Quick sort
    (C) Bubble sort
    (D) Selection sort
    (E) Insertion sort

登入後即可作答並保存紀錄。

這一題的完整詳解

本題考查各種排序演算法的「最差情況」時間複雜度。Big-O 符號用來描述演算法效率的上限。

我們來分析各選項的演算法在最差情況下的時間複雜度:

(A) Merge sort (合併排序):

  • 時間複雜度:最好、平均、最差均為 O(nlog⁡n)O(n \log n)。
  • 這是因為合併排序總是將列表分成兩半,然後合併,其分割和合併的過程穩定。

(B) Quick sort (快速排序):

  • 時間複雜度:最好 O(nlog⁡n)O(n \log n),平均 O(nlog⁡n)O(n \log n),最差 O(n2)O(n^2)。
  • 最差情況發生在每次分割時,選取的基準點(pivot)都是最小或最大的元素,導致分割極不平衡,例如輸入的陣列已經排序或逆序排序。

(C) Bubble sort (氣泡排序):

  • 時間複雜度:最好 O(n)O(n) (如果陣列已排序且有優化),平均 O(n2)O(n^2),最差 O(n2)O(n^2)。
  • 在最差情況下(例如逆序排序),需要進行大量的交換。
🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 5 題

  1. Which of the following sorting method has the largest worst space complexity in Big-O?
    (A) Merge sort
    (B) Quick sort
    (C) Bubble sort
    (D) Radix sort
    (E) Heap sort

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查各種排序法的「最壞情況額外空間複雜度(worst-case auxiliary space complexity)」。

令輸入資料筆數為 nn:

  • 額外空間複雜度:排序過程除原始輸入資料外,額外使用的陣列、佇列、遞迴堆疊等記憶體。
  • Big-O 用來表示輸入規模增加時,空間需求的成長上限。

常見排序法的最壞額外空間如下:

排序法最壞額外空間複雜度
Merge sortO(n)O(n)
Quick sortO(n)O(n)
Bubble sortO(1)O(1)
Radix sortO(n+k)O(n+k)
Heap sortO(1)O(1)

其中,Radix sort 的 kk 通常代表數字的基底、鍵值範圍或桶子的數量。


解題方法

比較各選項的最壞空間複雜度即可。

Radix sort 通常需要:

  1. 儲存輸入資料的暫存結構,空間為 O(n)O(n);
  2. 儲存計數陣列或桶子,空間為 O(k)O(k)。

因此總空間為:

O(n)+O(k)=O(n+k)O(n)+O(k)=O(n+k)

由於題目未指定 kk 為固定常數,應保留 kk 這個變數。因此 O(n+k)O(n+k) 的一般形式比單純的 O(n)O(n) 更大,故選擇 Radix sort。


選項分析

(A) Merge sort

Merge sort 使用分割合併策略。合併兩個已排序序列時,通常需要額外的暫存陣列:

O(n)O(n)

遞迴呼叫堆疊通常為 O(log⁡n)O(\log n),但主要空間由合併用的暫存陣列決定,因此總額外空間為:

O(n)O(n)

不是本題最大者,故錯誤。

(B) Quick sort

Quick sort 的最壞情況可能每次都選到最差的 pivot,使分割成為:

(n−1)+0(n-1)+0

此時遞迴深度為 O(n)O(n),所以遞迴堆疊的最壞空間為:

O(n)O(n)
🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 6 題

  1. Which of the following statement is true? A, B, C are three classes, and B is derived from A.
    (A) A accesses a private variable in B.
    (B) B accesses a protected variable in C.
    (C) A accesses a protected variable in B.
    (D) C accesses a private variable in A.
    (E) B accesses a protected variable in A.

登入後即可作答並保存紀錄。

這一題的完整詳解

本題考查物件導向程式設計中類別繼承與存取權限(public, protected, private)的關係。

已知:

  • A, B, C 是三個類別。
  • B 是從 A 繼承而來的(B derived from A)。

我們逐一分析各選項:

(A) A 存取 B 的 private 變數:

  • private 變數只能在宣告的類別內部存取。A 是 B 的父類別,但 A 的成員函數無法直接存取 B 的 private 成員。這是錯誤的。

(B) B 存取 C 的 protected 變數:

  • 題目沒有說明 C 與 A 或 B 的關係。即使 C 是 A 的子類別,B 也無法直接存取 C 的 protected 變數,除非 B 也是 C 的子類別(或是 C 的父類別,但 protected 變數通常也有限制)。如果 C 與 A, B 無關,則更不可能。這是錯誤的。
🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 7 題

  1. In the following statements
    int a = 5;
    int b = 7;
    int c = a * 2 > pow(pow(a, 2) + pow(b, 2), 0.5) && !(a+ ++b < rand()%10 + 3)? pow(a, 2) % b: pow(b, 2)/ a;
    which of the following choice is the correct answer of c?
    (A) 12
    (B) 3
    (C) 4
    (D) 1
    (E) 9

登入後即可作答並保存紀錄。

這一題的完整詳解

本題為經典的 C/C++ 程式語言綜合運算子考題,核心考核觀念包含:運算子優先順序與結合律(Operator Precedence & Associativity)、邏輯運算子的短路求值機制(Short-circuit Evaluation)、前綴遞增運算子的副作用(Side Effect of Pre-increment Operator ++)與序列點(Sequence Point),以及三元條件運算子(Ternary Operator ?:)的求值邏輯。


完整解題過程

已知初始變數狀態為:
a=5a=5
b=7b=7

待評估的表達式為:
c = a * 2 > pow(pow(a, 2) + pow(b, 2), 0.5) && !(a+ ++b < rand()%10 + 3)? pow(a, 2) % b: pow(b, 2)/ a;

步驟一:分析運算式的整體結構與優先順序

根據 C/C++ 運算子優先順序:

  1. 算術與函數呼叫(如 pow、*、+)優先權最高。
  2. 關係運算子(>、<)優先權次之。
  3. 邏輯與(&&)優先權低於關係運算子。
  4. 三元條件運算子(? :)優先權低於邏輯運算子。

因此,表達式可拆解為條件式與兩個分支:

  • 條件判斷式(Condition):[a * 2 > pow(pow(a, 2) + pow(b, 2), 0.5)] && [!(a+ ++b < rand()%10 + 3)]
  • True 分支(expr1):pow(a, 2) % b
  • False 分支(expr2):pow(b, 2)/ a

步驟二:評估條件判斷式之左式(LHS)

左式為:a * 2 > pow(pow(a, 2) + pow(b, 2), 0.5)

  1. 計算左側算式:
    a×2=5×2=10a \times 2 = 5 \times 2 = 10
  2. 計算右側 pow 數學函數:
    pow(a,2)=52=25pow(a, 2) = 5^2 = 25
    pow(b,2)=72=49pow(b, 2) = 7^2 = 49
    pow(a,2)+pow(b,2)=25+49=74pow(a, 2) + pow(b, 2) = 25 + 49 = 74
    pow(74,0.5)=74≈8.6023pow(74, 0.5) = \sqrt{74} \approx 8.6023
  3. 進行比較:
    10>8.602310 > 8.6023
    此不等式成立,故 LHS 評估結果為真(True,數值為 11)。

步驟三:評估條件判斷式之右式(RHS)與短路求值機制

為什麼右式必須被執行?
在 C/C++ 中,邏輯與運算子 && 具備短路求值(Short-circuit Evaluation)特性。當且僅當 LHS 為假(00)時,程式才會跳過 RHS。由於本題 LHS 評估結果為真(11),程式必須繼續執行 RHS 以確定整體邏輯值。

右式為:!(a+ ++b < rand()%10 + 3)

  1. 前綴遞增運算子 ++b 的副作用:
    前綴遞增會先將變數加 11 後再回傳該值。
🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 8 題

  1. In the following statements
    int i = 3, j = 5, k = 0;
    void main() {
    do {
    i = i * j;
    plus(i, j);
    if (2000 < i) {
    break;
    }
    k++;
    } while (true);
    void plus(int a, int b) {
    }
    a++;
    b++;
    k++;
    which of the following choice is the correct answer of a?

登入後即可作答並保存紀錄。

這一題的完整詳解

本題考查 C 語言的程式碼執行流程,包括迴圈(do-while)、函數呼叫、變數作用域以及 break 語句的影響。

給定的程式碼片段:

int i = 3, j = 5, k = 0;

void plus(int a, int b) {
    a++;
    b++;
    k++; // 注意:這裡修改的是全域變數 k
}

void main() {
    do {
        i = i * j;
        plus(i, j); // 呼叫 plus 函數
        if (2000 < i) {
            break; // 跳出 do-while 迴圈
        }
        k++; // 如果沒有 break,則 k 遞增
    } while (true); // 無限迴圈,除非遇到 break
}

題目詢問 main 函數結束時,變數 a 的值。
但問題是:main 函數中並沒有定義變數 a,而且 plus 函數中的 a 是傳入的參數,是一個區域變數(local variable),它在 plus 函數結束後就會被銷毀,並且對 main 函數中的任何變數(包括 a,如果有的話)沒有影響。

讓我們仔細檢查程式碼:

  • main 函數內部有 i, j, k 這三個全域變數(或者是在 main 之前定義,視為全域)。
  • plus 函數接收兩個整數參數 a 和 b,並傳遞了 i 和 j 的值給它們。
  • 在 plus 函數內部,a++ 和 b++ 操作的是傳入的參數 a 和 b,而不是 main 函數中的 i 和 j。這些參數是值傳遞(pass by value),修改它們不會影響到呼叫者。
  • plus 函數內部修改了全域變數 k (k++)。

程式執行流程分析:

第一次迴圈迭代:

  • i = 3, j = 5, k = 0 (初始值)
  • i = i * j = 3 * 5 = 15
  • 呼叫 plus(i, j),即 plus(15, 5)。
    • 在 plus 函數內:
      • a (參數) = 15, b (參數) = 5
      • a++ => a (參數) 變為 16
      • b++ => b (參數) 變為 6
      • k++ => 全域變數 k 變為 1
    • plus 函數執行完畢,參數 a 和 b 被銷毀。
  • i 的值是 15。
  • 檢查 if (2000 < i) => if (2000 < 15) 是 False。
  • k++ => 全域變數 k 變為 2。
  • while (true) => 繼續迴圈。

第二次迴圈迭代:

  • i = 15, j = 5, k = 2 (來自上一次迭代)
  • i = i * j = 15 * 5 = 75
  • 呼叫 plus(i, j),即 plus(75, 5)。
    • 在 plus 函數內:
      • a (參數) = 75, b (參數) = 5
      • a++ => a (參數) 變為 76
      • b++ => b (參數) 變為 6
      • k++ => 全域變數 k 變為 3
    • plus 函數執行完畢。
  • i 的值是 75。
  • 檢查 if (2000 < i) => if (2000 < 75) 是 False。
  • k++ => 全域變數 k 變為 4。
  • while (true) => 繼續迴圈。

第三次迴圈迭代:

  • i = 75, j = 5, k = 4
  • i = i * j = 75 * 5 = 375
  • 呼叫 plus(i, j),即 plus(375, 5)。
    • 在 plus 函數內:
      • a (參數) = 375, b (參數) = 5
      • a++ => a (參數) 變為 376
      • b++ => b (參數) 變為 6
      • k++ => 全域變數 k 變為 5
    • plus 函數執行完畢。
  • i 的值是 375。
  • 檢查 if (2000 < i) => if (2000 < 375) 是 False。
  • k++ => 全域變數 k 變為 6。
  • while (true) => 繼續迴圈。

第四次迴圈迭代:

  • i = 375, j = 5, k = 6
  • i = i * j = 375 * 5 = 1875
  • 呼叫 plus(i, j),即 plus(1875, 5)。
    • 在 plus 函數內:
      • a (參數) = 1875, b (參數) = 5
      • a++ => a (參數) 變為 1876
      • b++ => b (參數) 變為 6
      • k++ => 全域變數 k 變為 7
    • plus 函數執行完畢。
  • i 的值是 1875。
🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 9 題

  1. In bubble sort, how many times the swap function is called for an array with the contents {43, 52, 38, 74, 12}?
    (A) 4
    (B) 5
    (C) 6
    (D) 7
    (E) 8

登入後即可作答並保存紀錄。

這一題的完整詳解

本題考查氣泡排序(Bubble Sort)演算法的執行過程,特別是交換(swap)操作的次數。
氣泡排序的目標是將陣列排序成遞增或遞減的順序。它通過重複地遍歷列表,比較相鄰的元素,並在它們的順序錯誤時交換它們。

給定的陣列:{43, 52, 38, 74, 12}
我們將進行遞增排序。

第一趟 (Pass 1):
比較並交換相鄰元素。

  • {43, 52, 38, 74, 12} -> 43 和 52 不需交換。
  • {43, 52, 38, 74, 12} -> 52 和 38 需要交換。陣列變為 {43, 38, 52, 74, 12}。Swap 1
  • {43, 38, 52, 74, 12} -> 52 和 74 不需交換。
  • {43, 38, 52, 74, 12} -> 74 和 12 需要交換。陣列變為 {43, 38, 52, 12, 74}。Swap 2
    第一趟結束後,最大的元素 74 被移動到最後。陣列變為 {43, 38, 52, 12, 74}。

第二趟 (Pass 2):
遍歷到倒數第二個元素。

  • {43, 38, 52, 12, 74} -> 43 和 38 需要交換。陣列變為 {38, 43, 52, 12, 74}。Swap 3
  • {38, 43, 52, 12, 74} -> 43 和 52 不需交換。
  • {38, 43, 52, 12, 74} -> 52 和 12 需要交換。陣列變為 {38, 43, 12, 52, 74}。Swap 4
    第二趟結束後,次大的元素 52 被移動到倒數第二個位置。陣列變為 {38, 43, 12, 52, 74}。
🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 10 題

  1. In the following statements
    int a = 0;
    for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 7; j++) {
    if (i > 3) {
    break;
    }
    if (j > 3 && j <5){
    continue;
    }
    else if(j > 5) {
    break;
    }
    i += a/2;
    j += a%3;
    a++;
    }
    }
    which of the following choice is the correct answer of a?
    (A) 4
    (B) 5
    (C) 6
    (D) 7

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查以下觀念:

  • 巢狀 for 迴圈的執行順序。
  • break 只會跳出目前所在的迴圈。
  • continue 會跳過本次迴圈剩餘程式,直接執行迴圈更新式。
  • 迴圈變數 i、j 可在迴圈本體內被修改。
  • C 語言整數除法:a / 2 會捨去小數部分。
  • a % 3 表示 aa 除以 33 的餘數。

內層迴圈每次執行的順序為:

  1. 判斷 i > 3。
  2. 判斷 j > 3 && j < 5。
  3. 判斷 j > 5。
  4. 執行 i += a/2、j += a%3、a++。
  5. 執行內層 for 的更新式 j++。

其中,若執行 break,本次迴圈後方的程式不會執行。


解題方法

依照程式實際執行順序追蹤 ii、jj 與 aa。

第一次外層迴圈:i=0i=0

初始狀態:

a=0,i=0,j=0a=0,\quad i=0,\quad j=0
執行前判斷結果本體內更新for 更新後
i=0,j=0,a=0i=0,j=0,a=0不符合 break 或 continuei=0+0/2=0i=0+0/2=0,j=0+0%3=0j=0+0\%3=0,a=1a=1j=1j=1
i=0,j=1,a=1i=0,j=1,a=1不符合 break 或 continuei=0+1/2=0i=0+1/2=0,j=1+1%3=2j=1+1\%3=2,a=2a=2j=3j=3
i=0,j=3,a=2i=0,j=3,a=2不符合 break 或 continuei=0+2/2=1i=0+2/2=1,j=3+2%3=5j=3+2\%3=5,a=3a=3j=6j=6
i=1,j=6,a=3i=1,j=6,a=3j > 5,執行 break不再執行後續更新離開內層迴圈

此時:

a=3,i=1a=3,\quad i=1

內層迴圈結束後,外層 for 的更新式執行 i++:

i=1+1=2i=1+1=2

第二次外層迴圈:i=2i=2

此時:

a=3,i=2a=3,\quad i=2
執行前判斷結果本體內更新for 更新後
🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 None 題

Please answer the following questions. For answers in code, any programming language (but not mixed) on
pseudocode is allowed. (60%)

  1. Please describe what is object-oriented programming (OOP) (5%), explain the benefits of OOP.(5%), please
    explain what is constructor (5%) and please write two constructors of a class (5%).

登入後即可作答並保存紀錄。

這一題的完整詳解

本題為申論題,主要考察物件導向程式設計 (OOP) 的基本概念、好處,以及建構子的定義與實作。

1. 物件導向程式設計 (Object-Oriented Programming, OOP) 是什麼?(5%)

物件導向程式設計 (OOP) 是一種程式設計典範 (programming paradigm),它將程式設計的概念圍繞著「物件」(object) 來組織。物件是現實世界中事物的抽象,它包含了資料 (data) 和操作這些資料的方法 (methods)。OOP 的核心思想是將複雜的系統分解成一系列相互作用的獨立物件,每個物件都封裝了自己的狀態 (state) 和行為 (behavior)。

OOP 的主要特徵包括:

  • 封裝 (Encapsulation):將資料 (屬性) 和操作資料的方法綁定在一起,形成一個獨立的單元(物件)。這可以隱藏物件的內部實現細節,並只暴露必要的接口,從而提高程式的模組化和安全性。
  • 繼承 (Inheritance):允許一個類別 (子類別或衍生類別) 繼承另一個類別 (父類別或基底類別) 的屬性和方法。這有助於程式碼的重用,並建立類別之間的層次結構。
  • 多型 (Polymorphism):允許不同類別的物件對相同的訊息做出不同的回應。這通常通過方法重載 (method overloading) 和方法覆寫 (method overriding) 來實現,使得程式設計更加靈活和可擴展。
  • 抽象 (Abstraction):隱藏物件的複雜細節,只向使用者展示必要的、簡化的介面。這有助於降低程式的複雜性,並專注於解決問題的核心。

2. OOP 的好處是什麼?(5%)

物件導向程式設計帶來了許多顯著的好處:

  • 程式碼重用 (Code Reusability):通過繼承,可以重複使用現有類別的程式碼,減少重複編寫,提高開發效率。
  • 可維護性 (Maintainability):封裝使得修改物件的內部實現不會影響到使用該物件的其他部分,從而更容易維護和更新程式碼。
  • 可擴展性 (Extensibility):可以通過新增類別或擴展現有類別來輕鬆地為系統添加新功能,而無需修改現有程式碼。
  • 模組化 (Modularity):將系統分解為獨立的物件,每個物件都可以單獨開發、測試和除錯,提高了程式的組織性和可讀性。
  • 易於理解和溝通 (Easier Understanding and Communication):OOP 的概念(物件、類別、繼承等)更貼近現實世界的思考方式,有助於開發團隊之間的溝通和理解。
  • 安全性 (Security):封裝通過隱藏內部資料和實現細節,可以防止外部程式碼錯誤地修改物件的狀態,提高程式的穩定性和安全性。

3. 建構子 (Constructor) 是什麼?(5%)

建構子(Constructor)是物件導向程式設計中,類別的一種特殊方法。它的主要作用是在創建一個類別的物件(實例)時,自動執行一些初始化操作,為物件的屬性設置初始值。

建構子的幾個關鍵特點:

  • 名稱與類別名稱相同:建構子的名稱必須與其所屬類別的名稱完全一致。
  • 沒有返回類型:建構子沒有返回類型,甚至連 void 關鍵字也不需要。
  • 自動調用:當使用 new 關鍵字創建物件時,建構子會被自動調用。
  • 可以有無參數或有參數:可以定義無參數建構子,也可以定義帶有多個參數的建構子,以便在創建物件時傳入不同的初始值。
  • 只能有一個無參數建構子:如果類別中定義了任何帶參數的建構子,則編譯器預設的無參數建構子將不會自動生成,此時若需要無參數建構子,則必須手動定義。

4. 請寫出一個類別的兩個建構子 (5%)

假設我們有一個名為 Car 的類別,它有兩個屬性:brand (品牌,字串) 和 year (年份,整數)。

🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 None 題

  1. Please define and declare a function with a nxn 2D integer array as parameter and without return value. The
    function searches the maximum element of each row and sorts the rows of the array in the ascending order
    based on the maximum elements of the rows.
    (20%)

For example:
3
5
22 84
27 14
133
5
33 9
3
27 141
4
22 84

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考核 C/C++ 程式設計中的三個核心觀念:

  1. 二維陣列作為函式參數的宣告與傳遞(2D Array Parameter Passing):
    在 C 語言中傳遞固定維度的二維陣列時,必須指定第二維(column)的大小,形式如 void sortRows(int arr[][N], int n),或使用 C99 變長陣列(VLA, Variable-Length Array)語法 void sortRows(int n, int arr[n][n])。在 C++ 中亦可利用指標陣列、二維向量或標頭常數定義。
  2. 列極值搜尋與關聯記錄(Finding Row Maximums):
    遍歷二維陣列的每一列(row),找出各列的最大值(maximum element),並記錄下來作為排序的權重依據。
  3. 根據特定鍵值(Key)對二維結構做整列交換排序(Row-wise Sorting):
    依據各列求出的最大值做升冪排序(Ascending Order),排序時需整列元素(或指向該列的位址)同步交換(Swap)。

解題方法

題目範例展示了一組 3×33 \times 3 二維陣列的排序過程:

  • 原陣列:
    • 第 0 列:[5, 22, 84] →\to 最大值為 8484
    • 第 1 列:[27, 14, 13](範例中排版為 27 14 13) →\to 最大值為 2727
    • 第 2 列:[3, 5, 33](範例中排版為 3 5 33) →\to 最大值為 3333
  • 各列最大值依序為:列 0(84)、列 1(27)、列 2(33)。
  • 依據最大值升冪排序(Ascending Order):27<33<8427 < 33 < 84。
  • 排序後各列順序應為:列 1 →\to 列 2 →\to 列 0。
    • 新第 0 列:[27, 14, 1](對應原列 1)
    • 第 1 列:[4, 3, 5] 或 [3, 5, 33](對應原列 2)
    • 第 2 列:[22, 84, ...](對應原列 0)
      (註:考卷原稿範例數字有局部排版換行折損,但語意完全明確,即「依每列的最大值由小到大重排各列」)。

演算法設計步驟:

  1. 函式宣告與定義:定義無回傳值(void)之函式,傳入 n×nn \times n 二維陣列及其維度 nn。
  2. 提取各列最大值:建立大小為 nn 的輔助陣列 maxVal,雙層迴圈掃描每一列取得最大值。
  3. 依最大值排序整列:使用簡易且直覺的排序法(如泡沫排序法 Bubble Sort 或選擇排序法 Selection Sort)。當比較發現前一列最大值大於後一列最大值時,除了交換 maxVal 中的代表值外,並以一個長度為 nn 的迴圈將原陣列中該兩列的所有元素逐一交換(Swap)。

程式碼實作

以下提供符合標準 C/C++ 規範且考場最易拿滿分的兩種標準寫法。

寫法一:標準 C99 / 現代 C++ 寫法(推薦)

#include <stdio.h>

/* 函式原型宣告 (Function Declaration) */
void sortRowsByMax(int n, int arr[n][n]);

/* 函式定義 (Function Definition) */
void sortRowsByMax(int n, int arr[n][n]) {
    int maxVal[n];

    // 步驟 1:找出每一列的最大值
    for (int i = 0; i < n; i++) {
        int currentMax = arr[i][0];
        for (int j = 1; j < n; j++) {
            if (arr[i][j] > currentMax) {
                currentMax = arr[i][j];
            }
        }
        maxVal[i] = currentMax;
    }

    // 步驟 2:依據 maxVal 進行升冪排序,並同步交換整列元素
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - 1 - i; j++) {
            if (maxVal[j] > maxVal[j + 1]) {
                // 交換最大值記錄
                int tempMax = maxVal[j];
                maxVal[j] = maxVal[j + 1];
                maxVal[j + 1] = tempMax;

                // 交換兩列的所有元素
                for (int k = 0; k < n; k++) {
                    int tempElem = arr[j][k];
                    arr[j][k] = arr[j + 1][k];
                    arr[j + 1][k] = tempElem;
                }
            }
        }
    }
}

寫法二:傳統 C89 語法(以巨集定義固定維度上限)

若考場要求相容傳統 C89(不支援 VLA):

🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 None 題

  1. To complete a digital content project, Arduino is a common prototyping tool. Please describe the benefits of
    Arduino (5%). Please draw a flow chart/architecture diagram with some descriptions and Arduino code, Unity
    code or pseudocode to show the concept to implement a digital content project. (15%)
    In this project, there is a board with 2D sensor array. When a user pitches a rubber ball to the board (like 棒球九
    宮格), it detects where the ball hits and a monitor shows where it hits on a grid with red dot.
    (The more complete concept is described, the higher score you get.)
    For example:
    On the monitor

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查「Arduino 感測器整合、事件偵測、座標轉換與互動媒體系統設計」。

完整系統可分成四層:

  1. 感測層:2D 感測器陣列偵測橡皮球撞擊位置。
  2. 嵌入式處理層:Arduino 讀取感測器訊號、判斷是否真的發生撞擊,並計算位置。
  3. 通訊層:Arduino 透過 USB Serial 將撞擊資料傳送給電腦。
  4. 視覺呈現層:Unity 接收資料,在九宮格對應位置顯示紅點、動畫或分數。

橡皮球撞擊後,感測器會產生電壓、電阻或數位訊號變化。若感測器能提供連續座標,可用加權平均估算撞擊中心:

x=∑i=1nsixi∑i=1nsix=\frac{\sum_{i=1}^{n}s_i x_i}{\sum_{i=1}^{n}s_i} y=∑i=1nsiyi∑i=1nsiy=\frac{\sum_{i=1}^{n}s_i y_i}{\sum_{i=1}^{n}s_i}

其中 sis_i 是第 ii 個感測器的反應強度,(xi,yi)(x_i,y_i) 是該感測器的位置。

若感測器陣列的實體範圍為寬 WW、高 HH,並切成 N×NN \times N 格,則九宮格中的欄、列可以由下式取得:

col=⌊xW/N⌋col=\left\lfloor \frac{x}{W/N} \right\rfloor row=⌊yH/N⌋row=\left\lfloor \frac{y}{H/N} \right\rfloor

為避免邊界值超出範圍,需限制:

0≤col<N,0≤row<N0\leq col<N,\qquad 0\leq row<N

Arduino 的優點

Arduino 是適合數位內容互動原型製作的開源微控制器平台,主要優點如下:

  1. 成本低:開發板與常用感測器價格低,適合快速製作展示原型。
  2. 容易學習:使用接近 C/C++ 的 Arduino 語法,並提供簡化的函式庫與開發環境。
  3. 輸入輸出介面完整:支援數位輸入、類比輸入、PWM、Serial、I2C、SPI 等介面,可連接按鈕、壓力感測器、馬達、燈光與顯示器。
  4. 開源且擴充性高:電路、軟體與函式庫資源豐富,能快速整合不同硬體。
  5. 適合快速迭代:修改程式後即可重新燒錄,方便測試互動設計與調整感測器參數。
  6. 容易與其他系統整合:可透過 USB Serial、藍牙、Wi-Fi 或網路模組與 Unity、Processing、網頁及手機應用程式溝通。

系統架構圖

以下假設感測器陣列能回傳橡皮球撞擊所造成的 x,yx,y 座標,並以 USB Serial 連接電腦:

橡皮球撞擊九宮格板
          │
          ▼
    2D 感測器陣列
          │
          │ 類比值/數位值
          ▼
       Arduino
          │
          ├─ 讀取感測器
          ├─ 濾除雜訊
          ├─ 判斷撞擊事件
          ├─ 計算 x、y 座標
          └─ 轉換成 row、col
          │
          │ USB Serial
          ▼
    Unity / 電腦程式
          │
          ├─ 解析撞擊資料
          ├─ 對應九宮格位置
          ├─ 顯示紅點動畫
          ├─ 播放音效
          └─ 計算分數
          │
          ▼
        螢幕畫面

解題方法

一、感測器配置

一種簡單實作方式是在板面下方配置 3×33\times3 個感測器:

S00   S01   S02
S10   S11   S12
S20   S21   S22

每個感測器負責一個九宮格區域。橡皮球落在某一格時,該位置的感測器反應值會明顯升高。

此方法可以直接判斷九宮格位置:

row=arg⁡max⁡i(si)row=\arg\max_i(s_i) col=arg⁡max⁡j(sj)col=\arg\max_j(s_j)

為提升定位精度,可將相鄰感測器的反應值做加權平均,使紅點不只顯示在格子中心,也能顯示更接近實際撞擊位置的座標。

二、撞擊判斷

感測器受到環境震動、手部碰觸或電氣雜訊時,也可能產生短暫訊號。因此需要設定:

  • 門檻值:訊號大於門檻才視為撞擊。
  • 去彈跳時間:一次撞擊後的短時間內忽略重複訊號。
  • 取樣與濾波:連續取樣數次,使用平均值或最大值降低雜訊。
  • 事件封鎖:等待訊號低於門檻後,才允許下一次撞擊。

三、資料格式

Arduino 將資料以一行文字傳給 Unity:

HIT,1,2,734,421

欄位意義如下:

HIT, row, col, x, y

例如 HIT,1,2,734,421 表示撞擊九宮格第 2 列、第 3 欄,板面座標為 (734,421)(734,421)。


Arduino 程式碼

以下程式以九個類比感測器為例。實際硬體可替換成壓力感測器、壓電片、紅外線遮斷器或其他 2D 感測器。

🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

其他考古題