113 國安局特考三等 資訊組(選試英文) 計算機概論 考古題詳解
第 一 題25 分
請將以下 IEEE-754 單倍精確度(32 bit)浮點數格式(二進位)轉成「十進位浮點小數」。
Sign(1 bit):0
Exponent(8 bits, bias=127):10000011
Fraction(23 bits):10100000000000000000000
再請針對十進位浮點小數 表達成 IEEE-754 格式後,寫出其 Exponent 部位「最後 4 bits 的二進位值」。
最後請將十六進位資料 C0F80000 表示成 IEEE-754 單倍精確度浮點數格式,寫出 Fraction 部位「最前面 4 bits 的二進位值」,和此十六進位資料的「十進位浮點小數」。
登入後即可作答並保存紀錄。
核心觀念
IEEE-754 單倍精確度浮點數由 1 位符號位元、8 位指數欄位及 23 位小數欄位組成。正規化數的數值為
其中 是符號位元, 是指數欄位所表示的無號整數, 是指數偏移值(bias)。正規化數的有效數字前有隱含的 。
解題方法
- 依二進位格式求十進位值
符號位元為 ,表示正數。指數欄位為
因此實際指數為 。Fraction 為 ,加上隱含的首位 ,有效數字為
故數值為
- 將 轉成 IEEE-754,求指數最後 4 位
符號位元為 。先將絕對值轉為二進位:
正規化後為
實際指數為 ,加上 bias:
指數欄位最後 4 位為 0011。
- 解讀十六進位資料 C0F80000
逐位轉為二進位:
第 二 題25 分
臺灣科技公司規劃網路,其中財務部門使用 C 等級(class C)的網路系統並手動設定 IP,子網路遮罩為 255.255.255.224。
其中,財務主管小明的 IP 為 140.123.100.89,員工佳佳的 IP 為 140.123.100.182。
請寫出小明的網路位址、廣播位址(以十進位表示);以及說明財務部門的網路可以切割成幾個子網路、每個子網路設定可用主機電腦數量。
最後,請說明手動設定電腦 IP 位址時,子網路遮罩(Subnet Mask)與預設閘道的功能。
登入後即可作答並保存紀錄。
核心觀念
本題考查子網路遮罩的 CIDR 前綴、網路位址與廣播位址的判定,以及子網路與可用主機數的計算。
255.255.255.224 的二進位表示中,前 27 位是網路位元、後 5 位是主機位元,因此前綴長度為 /27。在傳統 Class C 的 /24 網路中,向主機位元借用 3 位作為子網路位元。
解題方法
遮罩最後一個位元組為 224,二進位是 11100000,所以每個子網路的位址區塊大小為:
各子網路在最後一個位元組的範圍依序為 0–31、32–63、64–95、96–127、128–159、160–191、192–223、224–255。
小明的 IP 為 140.123.100.89,最後一個位元組 89 落在 64–95 區間,因此該子網路的網路位址是區間起點 64,廣播位址是區間終點 95:
- 網路位址:
140.123.100.64 - 廣播位址:
140.123.100.95
也可用位元運算表示:
此子網路最後 5 位是主機位元,主機位元全為 0 得到 .64,全為 1 得到 .95。
子網路數與可用主機數
第 三 題25 分
某城市有景點 A~E,其連接的道路均為單行道。單行道起點、終點與距離的資訊如下:
A->B(20)、A->C(25)、A->D(11)、B->C(25)、B->E(18)、C->D(27)、C->E(12)、D->B(24)、E->A(22)。
請畫出「起始點為 B」之廣度優先走訪樹狀圖,其中每一個景點只出現一次。
另外,請畫出根節點「起始點為 B」、其他景點為葉節點的展開樹,找出 B->D 景點的所有路徑與最短路徑,以及所經過之景點及其距離。
最後,請說明上面最短路徑走訪方法的演算步驟。
登入後即可作答並保存紀錄。
核心觀念
本題考查有向加權圖的廣度優先搜尋(Breadth-First Search, BFS)、展開樹與加權最短路徑。
- BFS依距離起點的「邊數」由少至多逐層走訪;每個頂點第一次被發現時標記,避免重複走訪。
- 展開樹保留從根節點出發的各種路徑分支。題目要求其他景點作為葉節點,因此到達某景點後不再由該節點向下展開;路徑中可以重複出現景點。
- 道路距離是邊的權重。路徑總距離為沿途道路距離之和;最短路徑問題可用 Dijkstra 演算法求解。
解題方法
一、起點為 B 的 BFS 走訪樹
依題目道路方向,從 B 出發的鄰接景點依序為 C、E。以下以題目列出的道路順序處理同層鄰點:
- 將 B 入隊並標記。
- 取出 B,發現 C、E,將兩者入隊並標記。
- 取出 C,發現尚未走訪的 D,將 D 入隊並標記;C→E 指向已標記的 E,不再加入。
- 取出 E,E→A 尚未走訪,將 A 入隊並標記。
- 取出 D,D→B 指向已走訪的 B,不再加入;最後取出 A,其鄰點皆已走訪。
BFS 走訪順序為 。各景點只在第一次發現時加入走訪樹,因此走訪樹為:
B
├── C
│ └── D
└── E
└── A
二、以 B 為根、其他景點為葉節點的展開樹
此處列出從 B 出發、每次沿有向道路前進,直到到達 A、C、D、E 其中一個景點就停止的所有分支。由於路徑可重複經過景點,展開樹不等同於 BFS 走訪樹。
B
├── C
│ ├── D
│ │ └── B
│ │ ├── C
│ │ │ └── D
│ │ └── E
│ └── E
│ └── A
│ ├── B
│ │ ├── C
│ │ │ └── D
│ │ └── E
│ ├── C
│ │ └── D
│ └── D
│ └── B
│ ├── C
│ │ └── D
│ └── E
└── E
└── A
├── B
│ ├── C
│ │ └── D
│ └── E
├── C
│ └── D
└── D
└── B
├── C
│ └── D
└── E
在展開樹中,到達 D 時即視為找到一條 B→D 路徑,並將 D 當作葉節點;其他分支則繼續展開,直到落在 A、C、D 或 E。由於道路網有迴圈,若不設定終止條件,展開樹會無限延伸。
三、B→D 的所有路徑及距離
依上述「到達 D 即停止」的展開方式,B→D 的路徑共有 5 條:
| 路徑 | 距離計算 | 總距離 |
|---|---|---|
| B→C→D | 52 | |
| B→C→D→B→C→D | 128 | |
| B→C→E→A→D | ,另加 B→C 的 25 | 70 |
| B→E→A→D | 51 |
第 四 題25 分
請完成計算中位數與眾數兩個方法(I)~(V)的空格程式,使程式正常運作,以輸出 Mean=1, Mode=5。
其中,中位數是將一組數值資料由小到大排列後,取最中間的數值為中位數。若資料個數為奇數,則取最中間的數值為中位數,例如 1, 2, 3, 3, 4, 6, 7, 7, 9 的中位數是 4;若資料個數為偶數,則取最中間兩個數值的平均為中位數,例如 1, 2, 3, 3, 4, 6, 7, 7, 8, 9 的中位數是 。
眾數則是指一組數字中出現次數最頻繁的數字。例如,2、3、3、5、7、10 的眾數是 3。
最後請說明此程式是否有不安全的地方,以及其原因。
#include <iostream> // 求中位數,若數量為奇數,回傳中間值,否則
#include <algorithm> // 回傳中間平均值
using namespace std;
class Compute {
public:
void setData(int *, int);
double getMedian();
double getMode();
private:
int *data, d_size;
// 取得 key 在 map 中的索引
int getIndex(int d[2][20], int key, int c) {
for (int i = 0; i < c; i++)
if (key == d[0][i])
return i;
return -1;
}
// 取得最大頻率值的 key
int getMaxValue(int d[2][20], int c) {
int maxKey = d[0][0];
int maxValue = d[1][0];
for (int i = 1; i < c; i++)
if (maxValue < d[1][i]) {
maxKey = d[0][i];
maxValue = d[1][i];
}
return maxKey;
}
};
// 設定資料並完成排序
void Compute::setData(int *d, int s) {
data = d;
d_size = s;
sort(data, data + d_size);
}
// 求中位數,若數量為奇數,回傳中間值,否則回傳中間平均值
double Compute::getMedian() {
if (d_size % 2 == ____) // (I)
return data[____]; // (II)
else
return (data[(d_size / 2) - 1] + ____)/2.0; // (III)
}
// 求眾數,統計數列各值出現頻率,找最大
double Compute::getMode() {
// d_map[0] 紀錄 Key,d_map[1] 紀錄頻率值
int d_map[2][20] = {0};
// d_map 數量
int map_count = 0;
for (int i = 0; i < d_size; i++) {
int index = getIndex(d_map, data[i], map_count);
if (index == ____) { // (IV)
d_map[0][map_count] = data[i];
d_map[1][map_count++] = 1;
} else
d_map[1][____] = d_map[1][index] + 1; // (V)
}
return getMaxValue(d_map, map_count);
}
int main() {
int data[10] = {5, 3, -4, 3, -1, 5, -1, -3, 5, -2};
Compute p;
p.setData(data, 10);
cout << "Mean=" << p.getMedian() << ", ";
cout << "Mode=" << p.getMode() << endl;
}
登入後即可作答並保存紀錄。
核心觀念
本題考查中位數、眾數的定義,以及 C++ 陣列索引與整數除法。
- 中位數(Median):資料由小到大排序後,奇數筆取正中間一筆;偶數筆取中間兩筆的平均。
- 眾數(Mode):出現頻率最高的數值。
getIndex找不到指定的值時回傳-1;找到時回傳該值在d_map中的索引。
解題方法
(I)~(III):計算中位數
資料筆數為奇數時,中央索引是 d_size / 2。C++ 的整數除法會捨去小數部分,因此可直接用整數除法取得中央位置。偶數筆時,取兩個中央位置的資料平均。
填入結果如下:
| 空格 | 填入內容 | 理由 |
|---|---|---|
| (I) | 1 | 奇數筆除以 2 的餘數為 1 |
| (II) | d_size / 2 | 奇數筆中央元素的索引 |
| (III) | data[d_size / 2] | 偶數筆右側中央元素 |
補完後:
double Compute::getMedian {
if (d_size % 2 == 1)
return data[d_size / 2];
else
return (data[(d_size / 2) - 1] + data[d_size / 2]) / 2.0;
}
本題資料排序後為:
-4, -3, -2, -1, -1, 3, 3, 5, 5, 5
共有 10 筆,中央兩筆是第 5 筆與第 6 筆,也就是索引 4 與索引 5 的 -1、3:
(IV)~(V):計算眾數
每讀入一筆資料,先用 getIndex 查詢該值是否已在 d_map 中:
- 若回傳
-1,代表第一次遇到此值,將值與初始頻率 1 寫入下一個空位。 - 若回傳有效索引,將該索引所對應的頻率加 1。
填入結果如下: