114 年 國立成功大學人工智慧科技碩士學位學程《程式設計(含資料結構與演算法)》
第 1 題3 分
Consider the following two functions written in C language:
void enqueue(int queue[], int *front, int *rear, int size, int value) {
if ((*rear + 1) % size == *front) {
printf("Queue is full\n");
return;
}
if (*front == -1) *front = 0;
*rear = (*rear + 1) % size;
queue[*rear] = value;
}
int dequeue(int queue[], int *front, int *rear, int size) {
if (*front == -1) {
printf("Queue is empty\n");
return -1;
}
int value = queue[*front];
if (*front == *rear) {
*front = *rear = -1;
} else {
*front = (*front + 1) % size;
}
return value;
}
Assume the queue Q with size = 5, initially empty (front = -1, rear = -1). What will be the content of the array Q after executing the given sequence of operations?
enqueue(Q, &front, &rear, size, 10);
enqueue(Q, &front, &rear, size, 20);
dequeue(Q, &front, &rear, size);
enqueue(Q, &front, &rear, size, 30);
enqueue(Q, &front, &rear, size, 40);
enqueue(Q, &front, &rear, size, 50);
dequeue(Q, &front, &rear, size);
enqueue(Q, &front, &rear, size, 60);
enqueue(Q, &front, &rear, size, 80);
enqueue(Q, &front, &rear, size, 90);
dequeue(Q, &front, &rear, size);
dequeue(Q, &front, &rear, size);
enqueue(Q, &front, &rear, size, 100);
(A) {40, 50, 60, 80, 90}
(B) {80, 90, 100, 50, 60}
(C) {-1, 50, 60, 80, 100}
(D) {50, 60, 80, 100, 40}
(E) {60, 80, 100, -1, 50}
登入後即可作答並保存紀錄。
核心觀念
本題考查循環佇列(circular queue)的索引運作方式:
-
front指向目前隊首元素。 -
rear指向目前隊尾元素。 -
索引超過陣列最後位置時,以模除運算繞回開頭:
-
佇列為滿的條件:
(*rear + 1) % size == *front -
佇列刪除元素時,只移動
front,程式並未將原陣列位置清為-1。
解題方法
依序追蹤 front、rear 與陣列內容。陣列位置依序為 Q[0] 至 Q[4]。
| 操作 | 動作結果 | front | rear | 陣列 Q[0..4] |
|---|---|---|---|---|
| 初始 | 空佇列 | -1 | -1 | {—, —, —, —, —} |
| enqueue 10 | 寫入 Q[0] | 0 | 0 | {10, —, —, —, —} |
| enqueue 20 | 寫入 Q[1] | 0 | 1 | {10, 20, —, —, —} |
| dequeue | 取出 10 | 1 | 1 | {10, 20, —, —, —} |
| enqueue 30 | 寫入 Q[2] | 1 | 2 | {10, 20, 30, —, —} |
| enqueue 40 | 寫入 Q[3] | 1 | 3 | {10, 20, 30, 40, —} |
| enqueue 50 | 寫入 Q[4] | 1 | 4 | {10, 20, 30, 40, 50} |
| dequeue | 取出 20 | 2 | 4 | {10, 20, 30, 40, 50} |
| enqueue 60 | 繞回寫入 Q[0] | 2 | 0 | {60, 20, 30, 40, 50} |
| enqueue 80 | 繞回寫入 Q[1] | 2 | 1 | {60, 80, 30, 40, 50} |
| enqueue 90 | 佇列已滿,未寫入 | 2 | 1 | {60, 80, 30, 40, 50} |
| dequeue | 取出 30 | 3 | 1 | {60, 80, 30, 40, 50} |
| dequeue | 取出 40 | 4 | 1 | {60, 80, 30, 40, 50} |
| enqueue 100 | 寫入 Q[2] | 4 | 2 | {60, 80, 100, 40, 50} |
執行 enqueue(90) 時:
第 2 題3 分
Given a node structure as shown below:
typedef struct Node {
int data;
struct Node* next;
} Node;
What will the following function do when used on a singly linked list?
void unknownFunction (Node* node) {
if (node == NULL || node->next == NULL) {
return;
}
node->data = node->next->data;
Node* temp = node->next;
node->next = node->next->next;
free(temp);
}
(A) The function will delete the specified node, including the last node in the list.
(B) The function will delete the specified node only if it is a middle node or any node except the last one.
(C) The function will produce a segmentation fault when applied to the last node in the list because it attempts to access node->next->data.
(D) The function will remove the node but corrupt the list structure if the deleted node has duplicate values in the list.
(E) None of the above is correct.
登入後即可作答並保存紀錄。
核心觀念
本題考查單向鏈結串列中「沒有前驅節點指標時,刪除指定節點」的技巧。
單向鏈結串列若要正常刪除節點,通常需要找到前一個節點,使其 next 指向被刪節點的下一個節點。本函式採用替代方法:
- 將下一個節點的資料複製到目前節點。
- 讓目前節點跳過下一個節點。
- 釋放原本的下一個節點。
因此,實際被 free() 的是 node->next,而不是傳入的 node。但從串列資料順序來看,傳入的節點內容已被其後繼節點取代,所以可視為刪除了指定節點。
解題方法
假設串列為:
A → B → C → D
呼叫函式並傳入指向 B 的指標:
unknownFunction(B);
執行過程如下:
node->data = node->next->data;
此時 B 節點的資料改成 C 的資料:
A → C → C → D
接著:
Node* temp = node->next;
node->next = node->next->next;
free(temp);
B 的 next 改為直接指向 D,並釋放原本的 C:
A → C → D
所以從串列的資料與連結結果而言,原本的 B 已被刪除。
但若傳入最後一個節點 D:
if (node == NULL || node->next == NULL) {
return;
}
因為 D->next == NULL,函式直接返回,不會進行刪除。
選項分析
(A) 錯誤
函式無法刪除最後一個節點。
最後一個節點的 next 為 NULL,會在條件判斷處直接返回。因此「包括最後一個節點」的敘述錯誤。
(B) 正確
傳入的節點只要不是最後一個節點,就能透過複製後繼節點資料並跳過後繼節點,達到刪除指定節點的效果。
第 3 題3 分
The following C code is provided. Analyze the functionality of the code and answer the question.
#include <stdio.h>
int operation1 (int parent[], int x) {
if (parent[x] != -1) {
int rootX = operation1 (parent, parent[x]);
parent[x] = rootX; // Path compression
return rootX;
}
return x;
}
void operation2(int parent[], int x, int y) {
int rootX = operation1 (parent, x);
int rootY = operation1 (parent, y);
if (rootX != rootY) {
parent[rootY] = rootX; // Union by linking root of y to root of x
}
}
int main() {
int parent[6] = {-1, -1, -1, -1, -1, -1};
parent[2] = 1;
parent[3] = 2;
parent[4] = 3;
operation1 (parent, 4);
operation2(parent, 1, 3);
operation2(parent, 5, 4);
for(int i=0; i<=5; i++){
printf("%d ", parent[i]);
}
return 0;
}
Which of the following statements is correct?
(A) In the function main(), operation1 (parent, 4) updates all nodes in the chain starting from 4, and operation2(parent, 1, 3) merges two different groups.
(B) The output of the program is “-1 -1 1 1 1 1”.
(C) The output of the program is "-1 5 1 2 3 -1".
(D) The function operation1() compresses paths, and the function operation2() merges groups if they have different representatives.
(E) The function operation1() creates a loop, and the function operation2() merges all elements into one group.
登入後即可作答並保存紀錄。
核心觀念
本題考查不相交集合資料結構(Disjoint Set Union, DSU),又稱 Union-Find,主要操作如下:
operation1(parent, x):尋找元素 所在集合的代表元(root)。operation2(parent, x, y):合併 與 所在的兩個集合。- 若
parent[x] == -1,表示 是集合代表元。 - 若
parent[x] != -1,表示 的父節點是parent[x]。
operation1() 使用路徑壓縮(path compression):找到代表元後,將搜尋路徑上的節點直接連到代表元,以降低之後的搜尋成本。
operation2() 先找出兩個元素的代表元,只有在代表元不同時才合併:
if (rootX != rootY) {
parent[rootY] = rootX;
}
這段程式採用「將 的代表元連到 的代表元」的方式合併,沒有使用集合大小或樹高判斷,因此嚴格來說不是完整的 union by rank 或 union by size。
解題方法:逐步追蹤 parent 陣列
初始陣列為:
int parent[6] = {-1, -1, -1, -1, -1, -1};
parent[2] = 1;
parent[3] = 2;
parent[4] = 3;
因此初始結構如下:
其中 的 `parent[1] = -1105$ 各自為獨立集合。
初始陣列:
| 索引 | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
parent[i] | -1 | -1 | 1 | 2 | 3 | -1 |
第一步:operation1(parent, 4)
搜尋路徑為:
找到代表元 後,遞迴返回時進行路徑壓縮:
parent[2] = 1parent[3] = 1parent[4] = 1
陣列變為:
| 索引 | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
parent[i] | -1 | -1 | 1 | 1 | 1 | -1 |
結構變為:
第二步:operation2(parent, 1, 3)
先尋找 的代表元:
再尋找 的代表元:
所以:
兩者代表元相同:
因此不進行合併,陣列維持:
-1 -1 1 1 1 -1
第三步:operation2(parent, 5, 4)
先尋找 的代表元:
再尋找 $4
第 4 題3 分
Consider the following two functions written in C language for the insertion into a hash table and the deletion from the table:
void insert(int table[], int size, int key) {
int index;
for (int i = 0; i < size; i++) {
index = (key % size + i * i) % size;
if (table[index] == -1 || table[index] == -2) {
table[index] = key;
return;
}
}
}
void delete(int table[], int size, int key) {
int index;
for (int i = 0; i < size; i++) {
index = (key % size + i * i) % size;
if (table[index] == key) {
table[index] = -2; // Mark as deleted
return;
}
}
}
Given that the keys are all non-negative integers and the keys to be deleted are always in the hash table. Which of the following implementations correctly searches for a specific key in the hash table, considering collision handling and the presence of deleted slots?
(A)
int search(int table[], int size, int key) {
int index;
for (int i = 0; i < size; i++) {
index = (key % size + i) % size; // Linear probing
if (table[index] == -1) { // Empty slot
return -1;
}
if (table[index] == key) { // Found
return index;
}
}
return -1; // Not found after checking all slots
}
(B)
int search(int table[], int table[], int size, int key) {
int index;
for (int i = 0; i < size; i++) {
index = (key % size + i * i) % size; // Quadratic probing
if (table[index] == key) { // Found
return index;
}
if (table[index] == -1 || table[index] == -2) { // Empty or deleted slot
return -1; // Key not found
}
}
return -1; // Not found after checking all slots
}
(C)
int search(int table[], int size, int key) {
int index;
for (int i = 0; i < size; i++) {
index = (key % size + i * i) % size; // Quadratic probing
if (table[index] == -1) { // Empty slot
return -1;
}
if (table[index] == key) { // Found
return index;
}
if (table[index] == -2) { // Deleted slot, continue probing
continue;
}
}
return -1; // Not found after checking all slots
}
(D)
int search(int table[], int size, int key) {
int index;
for (int i = 0; i < size; i++) {
index = (key % size + i * i) % size; // Quadratic probing
if (table[index] == -2) { // Deleted slot
return -1; // Incorrectly assumes key is not present
}
if (table[index] == key) { // Found
return index;
}
}
return -1; // Not found after checking all slots
}
(E) None of the above is correct.
登入後即可作答並保存紀錄。
核心觀念
本題考查開放定址法(open addressing)中的:
- 二次探測(quadratic probing)
- 碰撞處理
- 刪除標記(tombstone)
- 搜尋時的終止條件
插入與刪除所使用的探測位置皆為:
因此,搜尋也必須使用完全相同的二次探測序列。
表格中的特殊值意義如下:
-1:從未使用過的空槽。-2:原本曾存放資料,但資料已被刪除的槽位。- 非負整數:有效的鍵值。
刪除後必須標記為 -2,不能直接改成 -1。因為碰撞後的其他鍵可能位於該刪除位置之後,搜尋遇到 -2 時仍須繼續探測。
解題方法
搜尋流程應符合以下規則:
- 依照二次探測公式計算位置。
- 若找到
key,回傳該位置。 - 若遇到
-2,表示中間曾有資料被刪除,必須繼續搜尋。 - 若遇到
-1,表示該鍵不可能位於後續探測位置,可直接判定找不到。 - 若遇到其他鍵,代表發生碰撞,繼續探測。
例如令 size = 7,依序插入鍵值 1、8、15:
三個鍵的探測位置如下:
1:放入位置 。8:位置 被占用,探測位置 ,放入位置 。15:位置 被占用,接著探測 因此放入位置 。
刪除 1 後,位置 變成 -2。搜尋 15 時,探測順序為:
搜尋必須跳過位置 的 -2,才能在位置 找到 15。
選項分析
(A) 錯誤
此選項使用:
index = (key % size + i) % size;
這是線性探測,探測序列為:
但插入與刪除使用的是二次探測:
兩者探測位置不同,因此可能找不到實際存在的鍵。
此外,選項對 -2 會自然繼續搜尋,這部分是正確的;但探測公式錯誤,整體仍不正確。
(B) 錯誤
此選項的函式宣告為:
第 5 題4 分
Please successively insert the data pairs containing the following keys into an empty height-based min leftist tree: 10, 20, 30, 40, 50, 60, 70, 5, 4, 15, 16. After each insertion, the tree should still be a min leftist tree. Which of the following descriptions are correct for the resultant tree?
Note: In a tree, each step from top to bottom is called the level of a tree. The level count starts with 1 and increments by 1 at each level or step.
(A) The node containing key=10 has left child with key=30 and right child with key=20.
(B) The node containing key=10 and the node containing key=16 are siblings.
(C) After repeatedly performing the delete-min operation twice on the leftist tree, the node containing 20 is in the left subtree of the root.
(D) The difference of height between the left and right subtrees of the root is 2.
(E) The 3rd level of the tree has four nodes.
登入後即可作答並保存紀錄。
解題要點
- 左偏樹 (height‑based leftist tree) 以 最小根 為性質,插入即與單節點合併;
合併後若右子樹的 NPL (最短到空節點的距離) 大於左子樹,必須 交換左右子,再重新計算 NPL。 - 依序插入 10、20、30、40、50、60、70、5、4、15、16,最終樹形如下(每個節點標註其左/右子)
4
/ \
5 15
/ \
10 16
/ \
30 20
/ \ / \
40 50 60 70
- 逐條判斷敘述
第 6 題4 分
Please successively insert the data pairs containing the following keys into an empty min binomial heap (B-heap): 10, 20, 30, 40, 50, 60, 70, 5, 4, 15, 16. For each insertion of a single key, min-tree joining (pairwise combine) is performed. Which of the following descriptions are correct for the resultant B-heap?
Note: In a tree, each step from top to bottom is called the level of a tree. The level count starts with 1 and increments by 1 at each level or step.
(A) In the resultant B-heap, the maximum degree of binomial tree is 0.
(B) The number of singly linked circular lists in the B-heap to maintain siblings and roots is 7.
(C) After performing the delete-min operation on the B-heap once, the minimum degree of binomial tree is 0.
(D) After performing the delete-min operation on the B-heap twice, the root list of min trees contains nodes with keys as 10 and 20.
(E) After performing the delete-min operation on the B-heap three times, the node containing key=50 is at the 2nd level of a min tree.
登入後即可作答並保存紀錄。
在插入 11 個鍵後,最終的 B‑heap 由根度為 3、1、0 的三棵二項樹組成,根鍵分別為 5、4、16。
- A:最大度數為 3,非 0,錯誤。
- B:根列表 1 個,子列表僅在度數為 1、2、3 的節點上出現,共 4 個子列表,合計 5 個圓形單向鍊,非 7,錯誤。
第 7 題4 分
Given a tree containing n nodes, which of the following statements are correct?
(A) If the tree is a maximum cost spanning tree, the number of edges is n-1.
(B) If the tree is an AVL tree, the time complexity to delete an element is O(log n).
(C) If the tree is a compressed trie, the number of keys is n.
(D) If the tree is a red-black tree with n internal nodes, the rank of the root is at most log2(n+1).
(E) If the tree is a binary search tree, its height is O(log n).
登入後即可作答並保存紀錄。
核心觀念
本題考查樹的結構性質:
- 「樹」本身的節點與邊數關係。
- 各種平衡樹(AVL、紅黑樹)對高度的限制與因而衍生的時間複雜度。
- 壓縮字典樹(compressed trie)與普通字典樹在鍵與節點數目上的差異。
- 非平衡的二元搜尋樹在最壞情況下的高度。
(a) (A) If the tree is a maximum cost spanning tree, the number of edges is .
說明
- 「樹」的定義:連通且無迴圈的圖。
- 任意有 個節點的樹必有恰好 條邊,這與邊的權值(最大、最小)無關。
- 因此,最大成本生成樹(Maximum Cost Spanning Tree)仍是「樹」的一種,必符合此結構性質。
結論 【答案】True
(b) (B) If the tree is an AVL tree, the time complexity to delete an element is .
說明
- AVL 樹是高度平衡的二元搜尋樹,保證任意節點的左、右子樹高度差 。
- 由此可證其高度 滿足 (事實上 )。
- 刪除操作分為三步:
- 搜尋欲刪除的節點——需要沿著樹一路向下,耗時 。
- 刪除並可能以「左子樹最大」或「右子樹最小」替代,仍在 時間內完成。
- 重新平衡:沿刪除路徑向上檢查平衡因子,最多執行 次單/雙旋轉,每次 ,總共 。
結論 【答案】True
(c) (C) If the tree is a compressed trie, the number of keys is .
說明
- 壓縮字典樹(又稱 radix tree)將具有唯一公共前綴的單一路徑壓縮為單一邊。
第 8 題4 分
Consider the following AVL tree.
🖼️【此處有附圖,請對照原卷】
Which of the following statements are correct?
(A) The deletion of 35 requires rebalance operations.
(B) The insertion of 1 does not require rebalance operations.
(C) After deleting 9, the nodes containing keys 4 and 7 become siblings in the new tree.
(D) After successively deleting 35 and 60, the balance factor of the root in the new tree is 1.
(E) After successively inserting 27, 28, and 29, the balance factor of the root in the new tree is -1.
登入後即可作答並保存紀錄。
核心觀念
AVL 樹要求每個節點的平衡因子絕對值不超過 。以下採用
並令空子樹高度為 、葉節點高度為 。插入或刪除後,沿受影響的祖先節點更新高度;若平衡因子超出 ,就以單旋轉或雙旋轉恢復平衡。
解題方法
原樹的關鍵結構如下:
- 根節點為 ,左子樹根為 ,右子樹根為 。
- 的左右子節點為 ; 的子節點為 ,而 的右子節點為 ; 的右子節點為 。
- 的左右子節點為 ; 的右子節點為 , 的右子節點為 。
逐一依照二元搜尋樹的插入、刪除規則調整,再檢查受影響節點的平衡因子。
選項分析
(A) 錯誤。 刪除 後, 從有一個右子節點變成葉節點; 的左子樹高度為 ,右子樹高度為 ,所以 ,不需旋轉。根節點 仍符合 AVL 條件,因此此次刪除不需要重新平衡旋轉。
(B) 正確。 插入 後, 成為 的左子節點。節點 的左右子樹高度都為 ,高度維持不變;再往上檢查, 與 也都沒有失衡,因此不需旋轉。
第 9 題4 分
Considering the following two sequences, which are traversal results of a binary tree.
Inorder-traversal result: HDINBEJ A OKPFLCGM
Postorder-traversal result: HNIDJEBOPKLFMGCA
Please reconstruct the binary tree using the above two sequences. Which of the following descriptions are correct for the resultant binary tree?
Note: In a tree, each step from top to bottom is called the level of a tree. The level count starts with 1 and increments by 1 at each level or step.
(A) The balance factor of the root is 0.
(B) The height of the tree is 4.
(C) The total number of leaf nodes is 7.
(D) After performing a depth-first search starting at node B of the resultant tree, the shortest path from vertex B to vertex O in the spanning tree has 5 edges.
(E) The last element in the result of level-order traversal of the tree is P.
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- 二元樹的中序走訪(Inorder)
- 二元樹的後序走訪(Postorder)
- 由中序與後序唯一重建二元樹
- 平衡因子(Balance Factor)
- 樹高與層數
- 葉節點數量
- 深度優先搜尋(DFS)與樹上的最短路徑
- 層序走訪(Level-order Traversal)
重建規則如下:
- 後序走訪的最後一個節點必為目前子樹的根。
- 根在中序走訪中的左側,構成左子樹;右側構成右子樹。
- 依照相同規則遞迴處理左右子樹。
解題方法:重建二元樹
題目給定:
- 中序:
- 後序:
1. 找出根節點
後序走訪最後一個元素為 ,因此根節點是 。
中序中, 左側為:
右側為:
因此:
- 的左子樹包含
- 的右子樹包含
2. 重建左子樹
左子樹的後序序列為:
最後一個元素為 ,所以 是左子樹根。
中序中, 左側為 ,右側為 。
繼續分解:
- 的左子樹根為
- 的左子節點為
- 的右子樹根為
- 的左子節點為
- 的右子樹根為
- 的右子節點為
3. 重建右子樹
右子樹的後序序列為:
最後一個元素為 ,所以 是右子樹根。
中序中, 左側為 ,右側為 。
繼續分解:
- 的左子樹根為
- 的左子樹根為
- 的左子節點為
- 的右子節點為
- 的右子節點為
- 的右子樹根為
- 的右子節點為
完整二元樹如下:
A
/ \
B C
/ \ / \
D E F G
/ \ \ / \ \
H N J K L M
/ / \
I O P
選項分析
(A)根的平衡因子為 0
平衡因子定義為:
第 10 題4 分
Considering the following red-black tree, where a white node indicates a red node and a black node indicates a black node:
🖼️【此處有附圖,請對照原卷】
Which of the following statements are correct?
(A) After inserting into the tree, the number of black nodes becomes .
(B) After successively inserting and into the tree, the number of red nodes becomes .
(C) The deletion of from the tree may reduce the height of the tree.
(D) After successively deleting and from the tree, the rank of the root is .
(E) The deletion of can be done by moving to the root.
登入後即可作答並保存紀錄。
核心觀念
紅黑樹的插入與刪除會依照節點顏色及局部結構進行重新著色、旋轉,以維持紅黑樹性質。插入新節點時先將其設為紅色;刪除黑色節點時,可能需要透過旋轉與重新著色修復黑色高度。
本題的「rank of the root」依紅黑樹常用定義,指從根到外部 NIL 葉節點的路徑上,黑色節點的數目;計算時不包含 NIL。
解題方法
圖中的根為黑色 ;左子樹根為黑色 ,其子女為黑色 ,紅色葉節點包括 。右子樹根為黑色 ,其左子為紅色 、右子為黑色 ; 的子女為黑色 , 的右子為紅色 ,而 的左子為紅色 。依題意逐項模擬插入或刪除,並在每次操作後檢查顏色、黑色高度與樹高。
選項分析
(A) 正確。 插入 後, 成為紅色節點 的左子。此時父節點 與叔叔節點 都是紅色,將 改為黑色,將祖父節點 改為紅色。原本有 個黑色節點;此次重新著色淨增加 個黑色節點,因此共有 個黑色節點。
(B) 正確。 插入 時,它成為黑色節點 的紅色右子。接著插入 ,成為紅色節點 的左子;此時其父節點 與叔叔節點 都是紅色,因此將 改為黑色,並將祖父節點 改為紅色。初始有 個紅色節點,插入兩個紅色節點後有 個;重新著色將兩個節點改黑、將一個節點改紅,最後共有 個紅色節點。
第 11 題4 分
Considering the following adjacency matrix:
Please reconstruct the undirected graph based on the above adjacency matrix. Which of the following statements related to the resultant graph are correct?
(A) The breadth-first search starting at vertex produces a spanning tree with vertices.
(B) The degree of vertex is .
(C) The graph has one articulation point.
(D) The graph has one connected component.
(E) The graph has two cycles.
登入後即可作答並保存紀錄。
核心觀念
本題考查如何由無向圖的鄰接矩陣還原邊,並判斷廣度優先搜尋(BFS)、頂點度數、割點、連通分量與環的數量。
無向圖的鄰接矩陣會對稱;若矩陣第 列、第 欄為 ,就代表頂點 與頂點 相鄰。頂點的度數是與它相接的邊數;若移除某頂點會增加連通分量數,該頂點就是割點。
解題方法
圖中的矩陣列與欄標示為 至 ;依矩陣的 還原無向邊後,可得兩個連通部分: 形成一個四邊環; 形成一個三角形,且頂點 另連到頂點 。
將矩陣中的相鄰關係各記為一條無向邊,邊集合為:
從頂點 執行 BFS,只能到達其所在連通部分的頂點 。移除頂點 後,頂點 會與頂點 分離,因此 是割點。圖中共有兩個環: 與 。
選項分析
第 12 題5 分
Considering the following B-tree of order :
🖼️【此處有附圖,請對照原卷】
Successively insert , , , and into the above B-tree, one at a time, and then delete , , , , and , one at a time. Please show the new tree after completing all the insertion and deletion operations.
登入後即可作答並保存紀錄。
核心觀念
圖中的 B-tree 階數為 4,因此每個節點最多有 4 個子節點、3 個鍵值;非根節點至少要有 1 個鍵值。節點插入後若超過 3 個鍵值,就將中間鍵值提升到父節點;刪除造成節點缺鍵時,先向有多餘鍵值的兄弟借,否則與兄弟及父節點分隔鍵合併。若根節點因合併而空掉,樹高會減少一層。
解題方法
原圖的根節點是 ,三個子節點依序為 、、。以下以 表示一個節點,並依由上到下、由左到右記錄各層節點。
插入 時,右側節點分裂,提升 ;再把 插入右側新節點:
- 插入 後:根為 ;下一層為 、、、。
接著插入 與 :
- 插入 後:根為 ;下一層為 、、、。
- 插入 後:根為 ;下一層為 、、、。
插入 時,先分裂滿載的根,將 提升為新根;再分裂左側的 ,將 提升到父節點,最後將 插入 :
- 插入 後:根為 ;第二層為 、;第三層依序為 、、、、。
接著依序刪除:
第 13 題5 分
Considering the following graph :
🖼️【此處有附圖,請對照原卷】
(a) [1%] Write out the cost of the maximum cost spanning tree for graph .
(b) [2%] Write out the last edge selected into the maximum cost spanning tree for graph when using Kruskal’s method.
(c) [2%] Write out the 5th edge selected into the maximum cost spanning tree for graph when using Prim’s method starting with vertex .
登入後即可作答並保存紀錄。
核心觀念
最大生成樹是在連通圖中,選出涵蓋所有頂點且不含環的邊集合,使邊權總和最大。若圖有 個頂點,生成樹必須恰有 條邊。Kruskal 法由邊權大到小挑選不會形成環的邊;Prim 法則從指定頂點開始,每次加入一條連接已選頂點與未選頂點的最大權重邊。
解題方法
圖中有 共 個頂點;邊與權重為 。因此生成樹需選 條邊。
(a) 最大生成樹的成本
以 Kruskal 法將邊依權重由大到小檢查:
- 選 ,這些邊都不形成環。
- 會在 間形成環,略過。
- 選 ,將頂點 接入。
- 會形成環,略過。
- 選 ,將頂點 接入;此時共有 條邊,涵蓋全部頂點。
最大生成樹成本為
第 14 題10 分
Given a set of size , where , we use the following algorithm to perform clustering and labeling:
F(S)
1 If |S| == 2 then return;
2 Apply a clustering algorithm with a time complexity of \Theta(\lg n) to divide the set S into three clusters, S_1, S_2, and S_3, and label them where |S|=n, |S_1|=|S_2|=\sqrt{n}, and |S_3|=n-2\sqrt{n}.
3 Call F(S_1)
4 Call F(S_2)
Let represent the time required to use this algorithm to cluster and label a set of size . Provide an asymptotic tight bound () for , assuming that is a constant for sufficiently small .
登入後即可作答並保存紀錄。
核心觀念
本題考查遞迴時間複雜度,以及如何依照題目給定的輸入規模分析遞迴深度。每次呼叫會產生兩個大小為 的遞迴子問題; 不會再遞迴處理,因此不會產生額外的遞迴成本。
解題方法
每個大小為 的呼叫,先花 時間進行分群與標記,再遞迴處理兩個大小為 的集合。因此:
題目給定 。每次取平方根會將指數中的 減少 :
令 。因為 ,遞迴式可改寫為:
且 。將等式除以 ,令 ,得到:
由此可得 ,所以:
又因為 ,且 ,故:
第 15 題10 分
We offer courses where each course has a start time , a finish time , and a weight . Two courses are considered compatible if their time intervals do not overlap. For simplicity, we can assume that the courses are sorted in non-decreasing order of their finish times, denoted as . Additionally, let for a course represent the largest index such that courses and are disjoint. We define if no course is disjoint from . Our goal is to find a set of mutually compatible courses such that the total weight of the courses in is maximized.
We have designed a recursive algorithm for this purpose, but we have omitted an essential part. Please assist us in completing the missing portion. Hint: This algorithm returns the value of the optimal solution to the problem consisting of courses .
登入後即可作答並保存紀錄。
核心觀念
本題考的是加權區間排程。每門課程 有開始時間 、結束時間 與權重 ;目標是在課程彼此相容的條件下,找出總權重最大的集合。
課程已依結束時間排序。對課程 , 表示在它之前,最後一門與它相容的課程索引;若不存在,則 。因此,選入課程 之後,能接在它之前的課程只可能來自 。
解題方法
考慮最優解是否包含第 門課程,分成兩種情況:
- **選入第 門課程:**可取得權重 ;其餘課程必須來自前 門,最佳總權重為 ,合計為 。
- **不選第 門課程:**最佳總權重為前 門課程的解,也就是 。
取兩者較大值,得到遞迴式:
所以題目空格應填:
第 16 題10 分
We aim to select courses from a pool of courses. Since this is still in the planning phase, each course has no specified start or finish times. Each course is characterized by its duration and weight . The total available classroom time is . We want to identify a subset of courses such that the total duration of courses in does not exceed and the total weight of is maximized.
To achieve this, we have developed a dynamic programming algorithm that uses an table to solve the problem. Here, represents the maximum total weight achievable when considering only the subset of courses and a classroom available for units of time. Write the recursive formula to compute .
登入後即可作答並保存紀錄。
核心觀念
本題考的是 0/1 背包問題。每門課最多選一次;在課程總時數不超過 的條件下,讓總權重最大。 表示只考慮前 門課、可用時間為 時的最大總權重。
解題方法
圖中第 16 題給定每門課的時長 與權重 ,可用教室時間為 ,並以表格 儲存子問題答案。
考慮第 門課時,分成兩種情況:若時長 超過目前可用時間 ,就不能選它;否則比較「不選第 門課」與「選第 門課」兩種方案,取權重較大者。因此遞迴式為:
其中,選第 門課後,剩餘容量為 ,所以加上 ;使用前一列 ,確保每門課最多選一次。
第 17 題10 分
Assuming that the available time for the classroom is unlimited, we instead focus on the course completion time. We aim to schedule courses, where each course is characterized by its duration and weight . In this schedule, the finish time of each course is the total duration of all courses scheduled before it, plus its duration. A schedule can be defined as a function , representing the order of course in the schedule. That is, if , course is scheduled before course . Therefore, the finish time of course is denoted as
This scheduling problem aims to minimize the total weighted finish time . Suppose we have courses with corresponding durations and weights . What is the value of the optimal schedule, that is, the minimum total weighted finish time?
登入後即可作答並保存紀錄。
核心觀念
這題考的是單機排程中的最小總加權完成時間。每門課依序進行,課程 的完成時間為 ,目標是最小化
適用的最佳排序法則是 Smith 法則:依 由小到大排序;等價地,也可依 由大到小排序。
解題方法與推導
用相鄰兩門課的交換來判斷最佳順序。設兩門課為 、,且在它們之前已排課程的總時間為 。
若先排 再排 ,兩門課對目標值的貢獻為
若先排 再排 ,貢獻為
前者減後者為 。因此,先排 較佳的條件是
所以將課程依 遞增排序,即可得到最佳順序。
計算過程
排序後的課程順序為
逐門課累加完成時間,並計算 :
| 順序 | 課程 | 完成時間 | |||
|---|---|---|---|---|---|
| 1 | 15 | 15 | 15 | 15 | 225 |
| 2 | 2 | 6 | 4 | 21 | 84 |
| 3 | 11 | 19 | 11 | 40 | 440 |
| 4 | 3 | 9 | 4 | 49 | 196 |
| 5 | 1 | 6 | 2 | 55 | 110 |
| 6 | 8 | 38 | 10 | 93 | 930 |
第 18 題10 分
The Floyd–Warshall algorithm can solve the all-pairs shortest-paths problem on a directed graph . Let be the weight of a shortest path from vertex to vertex for which all intermediate vertices are in the set , and let be an matrix. The Floyd–Warshall algorithm computes from as follows:
Please complete the above formula.
登入後即可作答並保存紀錄。
核心觀念
本題考 Floyd–Warshall 演算法的動態規劃遞迴式。 表示從頂點 到頂點 ,且中間頂點只允許取自 的最短路徑長度。
解題方法
圖中第 18 題給的是有向圖 ,並以 推算 ;要判斷最短路徑是否會經過新加入的中間頂點 。
若路徑不經過 ,長度為 ;若經過 ,路徑可拆成 與 兩段,長度為 。因此取兩種情況中較短者: