# APCS 觀念題 - 演算法與資料結構 ###### tags: `APCS` ## 第 1 題 List 是一個陣列,裡面的元素是 element,它的定義如下。 ```c struct element { char data; int next; } ``` List 中的每一個 element 利用 `next` 這個整數變數來記錄下一個 element 在陣列中的位置,如果沒有下一個 element,`next` 就會記錄 -1。所有的 element 串成了一個串列 (linked list)。例如在 list 中有三筆資料: |1|2|3| |-|-|-| |data = 'a'<br>next = 2|data = 'b'<br>next = -1|data = 'c'<br>next = 1| 它所代表的串列如下圖: ![](https://hackmd.io/_uploads/SkZKHJfB3.png) `RemoveNextElement` 是一個函式,用來移除串列中 `current` 所指向的下一個元素,但是必須保持原始串列的順序。例如,若 `current` 為 `3` (對應到 `list[3]`),呼叫完 `RemoveNextElement` 後,串列應為 ![](https://hackmd.io/_uploads/Byl58kGH2.png) 請問在下方程式碼中 (?) 應該填入的程式碼為何? ```c void RemoveNextElement(element list[], int current) { if (list[current].next != -1) { /*移除 current 的下一個 element*/ ___(?)___; } } ``` (A) `list[current].next = current;` (B) `list[current].next = list[list[current].next].next;` \(C\) `current = list[list[current].next].next;` (D) `list[list[current].next].next = list[current].next;` <!-- B --> ## 第 2 題 下方程式片段擬以輾轉除法求 `i` 與 `j` 的最大公因數。請問 `while` 迴圈內容何者正確? ```c i = 76; j = 48; while ((i % j) != 0) { ________________ ________________ ________________ } printf ("%d\n", j); ``` (A) `k = i % j;` `i = j;` `j = k;` (B) `i = j;` `j = k;` `k = i % j;` \(C\) `i = j;` `j = i % k;` `k = i;` (D) `k = i;` `i = j;` `j = i % k;` <!-- A --> ## 第 3 題 下方程式片段主要功能為:輸入六個整數,檢測並印出最後一個數字是否為六個數字中最小的值。然而,這個程式是錯誤的。請問以下哪一組測試資料可以測試出程式有誤? ```c #define TRUE 1 #define FALSE 0 int d[6], val, allBig; // ... for (int i = 1; i <= 5; i = i + 1) { scanf("%d", &d[i]); } scanf("%d", &val); allBig = TRUE; for (int i = 1; i <= 5; i = i + 1) { if (d[i] > val) { allBig = TRUE; } else { allBig = FALSE; } } if (allBig == TRUE) { printf("%d is the smallest.\n", val); } else { printf("%d is not the smallest.\n", val); } ``` (A) 11 12 13 14 15 3 (B) 11 12 13 14 25 20 \(C\) 23 15 18 20 11 12 (D) 18 17 19 24 15 16 <!-- B --> ## 第 4 題 下面哪組資料若依序存入陣列中,將無法直接使用二分搜尋法搜尋資料? (A) a, e, i, o, u (B) 3, 1, 4, 5, 9 \(C\) 10000, 0, -10000 (D) 1, 10, 10, 10, 100 <!-- B --> ## 第 5 題 給定一個 1x8 的陣列 `A`, `A = {0, 2, 4, 6, 8, 10, 12, 14}`。下方函式 `Search(x)` 真正目的是找到 `A` 之中大於 x 的最小值。然而,這個函式有誤。請問下列哪個函式呼叫可測出函式有誤? ```c int A[8] = {0, 2, 4, 6, 8, 10, 12, 14}; int Search(int x) { int high = 7; int low = 0; while (high > low) { int mid = (high + low) / 2; if (A[mid] <= x) { low = mid + 1; } else { high = mid; } } return A[high]; } ``` (A) `Search(-1)` (B) `Search(0)` \(C\) `Search(10)` (D) `Search(16)` <!-- D --> ## 第 6 題 下方函式兩個回傳式分別該如何撰寫,才能正確計算並回傳兩參數 `a`, `b` 之最大公因數 (Greatest Common Divisor)? ```c int GCD(int a, int b) { int r; r = a % b; if (r == 0) return __________; return _____________; } ``` (A) `a`, `GCD(b,r)` (B) `b`, `GCD(b,r)` \(C\) `a`, `GCD(a,r)` (D) `b`, `GCD(a,r)` <!-- B --> ## 第 7 題 若 `A[1]`、`A[2]`,和 `A[3]` 分別為陣列 `A[]` 的三個元素 (element),下列那個程式片段可以將 `A[1]` 和 `A[2]` 的內容交換? (A) `A[1] = A[2]; A[2] = A[1];` (B) `A[3] = A[1]; A[1] = A[2]; A[2] = A[3];` \(C\) `A[2] = A[1]; A[3] = A[2]; A[1] = A[3];` (D) 以上皆可 <!-- B --> ## 第 8 題 給定一整數陣列 `a[0]`、`a[1]`、...、`a[99]` 且 `a[k] = 3*k + 1`,以 `value = 100` 呼叫以下兩函式,假設函式 `f1` 及 `f2` 之 `while` 迴圈主體分別執行 `n1` 與 `n2` 次 (i.e, 計算 `if` 敘述執行次數,不包含 `else if` 敘述),請問 `n1` 與 `n2` 之值為何? 註: `(low + high) / 2` 只取整數部分。 ```c int f1(int a[], int value) { int r_value = -1; int i = 0; while (i < 100) { if (a[i] == value) { r_value = i; break; } i = i + 1; } return r_value; } ``` ```c int f2(int a[], int value) { int r_value = -1; int low = 0, high = 99; int mid; while (low <= high) { mid = (low + high) / 2; if (a[mid] == value) { r_value = mid; break; } else if (a[mid] < value) { low = mid + 1; } else { high = mid - 1; } } return r_value; } ``` (A) n1 = 33, n2 = 4 (B) n1 = 33, n2 = 5 \(C\) n1 = 34, n2 = 4 (D) n1 = 34, n2 = 5 <!-- D --> ---- ## 解答 |1|2|3|4|5| |-|-|-|-|-| |B|A|B|B|D| |6|7|8|9|10| |-|-|-|-|-| |B|B|D|-|-| [<< APCS 觀念題 - 遞迴](https://hackmd.io/@kaeteyaruyo/APCS-concept-recursion) | [目錄](https://hackmd.io/@kaeteyaruyo/APCS-concept-index)