114 高普考普通考試 資訊處理 程式設計概要 考古題詳解

114 年・高普考・普通考試・資訊處理
試題代碼 程式設計概要

第 一 題25 分

撰寫一個 Java 程式,使用遞迴計算給定正整數 nn 的「卡塔蘭數」(Catalan Number)C(n)C(n)。

其中 C(n)C(n) 定義為:

C(0)=1C(0)=1

C(n)=∑i=0n−1(C(i)×C(n−1−i))C(n)=\sum_{i=0}^{n-1}\left(C(i)\times C(n-1-i)\right)

使用者輸入 nn(nn 為非負整數且不超過 1515)。輸出 C(n)C(n),並使用 long 型別。

執行範例如下:例如輸入 n=4n=4,輸出 C(4)=14C(4)=14。

請完成下列程式碼:

(一)完成(A)程式碼(12 分)

(二)完成(B)程式碼(3 分)

(三)完成(C)程式碼(3 分)

(四)完成(D)程式碼(4 分)

(五)完成(E)程式碼(3 分)

import java.util.InputMismatchException; import java.util.Scanner;

public class JP2 { public static long catalan(int n) { (A) return sum; }

public static void main(String[] args) {
    Scanner scanner = (B)
    int n;

    try {
        n = scanner.nextInt();
        (C){
            System.out.println("輸入不合法!");
            scanner.close();
            return;
        }
    } catch (InputMismatchException e) {
        System.out.println("輸入不合法!");
        scanner.close();
        return;
    }

    (D)
    System.out.println((E) + result);
    scanner.close();
}

}

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

這一題的完整詳解

核心觀念

本題考遞迴函式、輸入合法性檢查,以及 long 型別的整數運算。

卡塔蘭數的定義為:

C(0)=1,C(n)=∑i=0n−1C(i)×C(n−1−i)(n≥1)C(0)=1,\qquad C(n)=\sum_{i=0}^{n-1} C(i)\times C(n-1-i)\quad(n\ge 1)

遞迴函式必須有終止條件:當 n=0n=0 時回傳 11;當 n>0n>0 時,依公式累加各組乘積。

解題方法

catalan 函式以 sum 儲存總和,初值設為 0。使用 for 迴圈令 ii 從 00 到 n−1n-1,將每一項 C(i)×C(n−1−i)C(i)\times C(n-1-i) 加入總和。當 n=0n=0 時,直接回傳 11,避免進入迴圈。

輸入檢查則需確認 nn 在 00 到 1515 之間;若不符合,輸出錯誤訊息並結束程式。nextInt 遇到非整數輸入時會拋出 InputMismatchException,由 catch 處理。

各空格答案

(A)

if (n == 0) {
 return 1L;
}
long sum = 0L;
for (int i = 0; i < n; i++) {
 sum += catalan(i) * catalan(n - 1 - i);
}

return 1L 是遞迴終止條件。其餘情況逐項套用遞迴定義,並以 long 儲存累加結果。

(B)

new Scanner(System.in);

建立讀取標準輸入的 Scanner。

(C)

if (n < 0 || n > 15)

檢查輸入是否超出題目指定範圍。此處使用邏輯或 ||,代表小於 00 或大於 1515 任一情況成立,就判定輸入不合法。

(D)

long result = catalan(n);

呼叫遞迴函式計算結果,並以 long 儲存。

(E)

"C(" + n + ")="

組成輸出標籤,例如 n=4n=4 時,輸出文字為 C(4)=14。

關鍵推導與驗算

依定義逐步計算:

🔒

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

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

免費註冊

第 二 題25 分

依據以下 C 程式碼,回答下列問題:

(一)第 6~12 行程式碼功能(4 分)

(二)第 13~17 行程式碼功能(4 分)

(三)第 19~29 行程式碼功能(7 分)

(四)第 30~32 行程式碼功能(2 分)

(五)第 33~41 行程式碼功能(4 分)

(六)第 42~45 行程式碼功能(2 分)

(七)第 46~49 行程式碼功能(2 分)

程式碼如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define MAXWL 21
  5. #define MAXWS 100
  6. int c1(const char* s1, const char* s2) {
  7. while (*s1 && *s1 == *s2) {
    
  8.     s1++;
    
  9.     s2++;
    
  10. }
  11. return *s1 - *s2;
  12. }
  13. int c2(const char* s) {
  14. int len = 0;
    
  15. while (s[len]) len++;
    
  16. return len;
    
  17. }
  18. int main() {
  19. char** words = malloc(MAXWS * sizeof(char*));
    
  20. int count = 0;
    
  21. char buffer[MAXWL];
    
  22. while (1) {
    
  23.     if (fgets(buffer, MAXWL, stdin) == NULL) break;
    
  24.     buffer[strcspn(buffer, "\n")] = '\0';
    
  25.     if (buffer[0] == '\0') break;
    
  26.     words[count] = malloc(c2(buffer) + 1);
    
  27.     strcpy(words[count], buffer);
    
  28.     count++;
    
  29. }
    
  30. for (int i = 0; i < count; i++) {
    
  31.     printf("Word: %s, Length: %d\n", words[i], c2(words[i]));
    
  32. }
    
  33. for (int i = 0; i < count - 1; i++) {
    
  34.     for (int j = 0; j < count - i - 1; j++) {
    
  35.         if (c1(words[j], words[j + 1]) > 0) {
    
  36.             char* temp = words[j];
    
  37.             words[j] = words[j + 1];
    
  38.             words[j + 1] = temp;
    
  39.         }
    
  40.     }
    
  41. }
    
  42. printf("Sorted words:\n");
    
  43. for (int i = 0; i < count; i++) {
    
  44.     printf("%s\n", words[i]);
    
  45. }
    
  46. for (int i = 0; i < count; i++) {
    
  47.     free(words[i]);
    
  48. }
    
  49. free(words);
    
  50. return 0;
    
  51. }

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

這一題的完整詳解

核心觀念

本題考查 C 語言的字串表示與操作、動態記憶體配置、氣泡排序,以及記憶體釋放。C 字串以 '\0' 作為結尾標記;malloc 配置記憶體,free 釋放記憶體。

解題方法與各小題

(一)第 6~12 行:自訂字串比較函式 c1

逐字比較 s1 和 s2 指向的字元。當兩個字元相同且尚未遇到字串結尾時,兩個指標各往後移一個字元。迴圈結束後回傳 *s1 - *s2:

  • 回傳值小於 0:s1 字典序小於 s2。
  • 回傳值等於 0:兩字串相同。
  • 回傳值大於 0:s1 字典序大於 s2。

若其中一個字串是另一個字串的前綴,較短字串的結尾字元 '\0' 小於另一字串接續的字元,因此較短字串排在前面。這個函式的比較方式與 strcmp 類似。

(二)第 13~17 行:自訂字串長度函式 c2

從索引 0 開始,逐一檢查 s[len];遇到 '\0' 前,每次將 len 加 1。最後回傳 len,也就是字串長度。

長度不包含結尾的 '\0'。例如字串 "cat" 的長度是 3,但儲存時需要 4 個字元位置,包含結尾標記。

(三)第 19~29 行:讀取輸入並動態儲存字串

  1. 第 19 行以 malloc 配置可容納 MAXWS 個 char* 的陣列,words 用來存放各字串的位址。
  2. 第 20 行將字串數量 count 設為 0;第 21 行建立可容納 MAXWL 個字元的輸入緩衝區。
  3. 第 22~23 行反覆讀取一行輸入。若 fgets 回傳 NULL,代表讀取失敗或遇到檔案結尾,便停止讀取。
  4. 第 24 行以 strcspn 找出換行字元 '\n' 的位置,並以 '\0' 取代,移除輸入字串尾端的換行符號。
  5. 第 25 行若讀到空字串,就停止輸入。
  6. 第 26 行依目前字串長度加上結尾標記所需空間,配置字串記憶體。長度為 LL 時,配置 L+1L+1 個位元組。
  7. 第 27~28 行將緩衝區內容複製到新配置的記憶體,並將字串數量加 1。
🔒

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

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

免費註冊

第 三 題25 分

依據以下 Python 程式碼,回答下列問題:

(一)第 2~8 行程式碼功能(4 分)

(二)第 10~12 行程式碼功能(3 分)

(三)第 14~15 行程式碼功能(4 分)

(四)第 17~20 行程式碼功能(4 分)

(五)第 22~24 行程式碼功能(3 分)

(六)第 26~29 行程式碼功能(4 分)

(七)第 31~32 行程式碼功能(3 分)

程式碼如下:

  1. def main():
  2. x = []
    
  3. for _ in range(3):
    
  4.     r = list(map(int, input().split()))
    
  5.     if len(r) != 3:
    
  6.         print("輸入不合法!")
    
  7.         return
    
  8.     x.append(r)
    
  9. print("運算前資料:")
  10. for r in x:
  11.    print(" ".join(f"{x:5d}" for x in r))
    
  12. sdm = sum(x[i][2 - i] for i in range(3))
  13. print(f"sdm: {sdm}")
  14. y = [[0] * 3 for _ in range(3)]
  15. for i in range(3):
  16.    for j in range(3):
    
  17.        y[j][2 - i] = x[i][j]
    
  18. print("運算後資料:")
  19. for r in y:
  20.    print(" ".join(f"{x:5d}" for x in r))
    
  21. for i, r in enumerate(y):
  22.    rs = sum(r)
    
  23.    ra = rs // len(r)
    
  24.    print(f"R{i}: rs = {rs}, ra = {ra}")
    
  25. if name == "main":
  26. main()
    

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

這一題的完整詳解

核心觀念

本題考查 Python 的串列(list)、輸入資料驗證、生成式與索引運算、二維串列的轉置與反斜對角線加總,以及整數除法。

輸入資料 x 與輸出資料 y 都是 3×33 \times 3 的二維串列。串列索引從 00 開始,因此元素 x[i][j] 表示第 i 列、第 j 欄。

解題方法與各段功能

(一)第 2~8 行:讀入並驗證三列資料(4 分)

x = [] 建立空串列,用來存放輸入的矩陣。for _ in range(3) 讓程式重複讀取三列;底線 _ 表示迴圈計數值不會在迴圈中使用。

第 4 行將一列輸入以空白切分,再逐一轉為整數,組成串列 r。例如輸入 1 2 3,會得到 r = [1, 2, 3]。

第 5~7 行檢查該列是否恰有三個數值;若數量不是 3,就印出「輸入不合法!」並以 return 結束 main。通過檢查後,第 8 行將該列加入 x。

因此,此段在讀入並驗證一個有三列、每列三個整數的 3×33 \times 3 矩陣。

(二)第 10~12 行:印出運算前資料(3 分)

第 10 行印出標題。第 11 行逐列取出 x 中的串列 r;第 12 行將該列各整數以欄寬 5 格的格式輸出,並以空白串接。

格式 :5d 表示將整數以十進位輸出,欄寬至少為 5;" ".join(...) 則將格式化後的各數字以空白連接。

(三)第 14~15 行:計算並輸出反斜對角線總和(4 分)

第 14 行以 sum 加總 x[i][2 - i],其中 i 依序為 0、1、2,因此取到:

x[0][2]+x[1][1]+x[2][0]x[0][2] + x[1][1] + x[2][0]

這是由右上角到左下角的反斜對角線元素總和。第 15 行以 f-string 印出變數 sdm 的值。

例如矩陣為

[123456789]\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9 \end{bmatrix}

則 sdm = 3 + 5 + 7 = 15。

(四)第 17~20 行:建立並填入轉置矩陣(4 分)

第 17 行建立一個 3×33 \times 3、元素初值皆為 0 的二維串列 y。外層與內層各建立三個元素。

第 18~20 行以雙層迴圈逐一處理 x[i][j],並執行:

y[j][2−i]=x[i][j]y[j][2-i] = x[i][j]

這不是一般的轉置,而是將原矩陣順時針旋轉 90∘90^\circ。例如原矩陣為

[123456789]\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9 \end{bmatrix}
🔒

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

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

免費註冊

第 四 題25 分

依據以下 C# 程式碼,回答下列問題:

(一)第 6~19 行程式碼功能(9 分)

(二)第 20~31 行程式碼功能(8 分)

(三)此程式輸出結果為何?(8 分)

程式碼如下:

  1. using System;
  2. namespace CSP4
  3. {
  4. class Program
    
  5. {
    
  6.     static bool CSP4_1(int x)
    
  7.     {
    
  8.         if (x < 0) return false;
    
  9.         int L = 0, R = x;
    
  10.        while (L <= R)
    
  11.        {
    
  12.            int M = L + (R - L) / 2;
    
  13.            long S = (long)M * M;
    
  14.            if (S == x) return true;
    
  15.            else if (S < x) L = M + 1;
    
  16.            else R = M - 1;
    
  17.        }
    
  18.        return false;
    
  19.    }
    
  20.    static long CSP4_2(int n)
    
  21.    {
    
  22.        if (n <= 1) return n;
    
  23.        long a = 0, b = 1;
    
  24.        for (int i = 2; i <= n; i++)
    
  25.        {
    
  26.            long temp = a + b;
    
  27.            a = b;
    
  28.            b = temp;
    
  29.        }
    
  30.        return b;
    
  31.    }
    
  32.    static void Main()
    
  33.    {
    
  34.        int[] arrays = { 9, 10, -4 };
    
  35.        foreach (var n in arrays)
    
  36.        {
    
  37.            Console.WriteLine($"{n} is CSP4_1? {CSP4_1(n)}");
    
  38.            Console.WriteLine($"CSP4_2({n}) = {CSP4_2(n)}");
    
  39.        }
    
  40.    }
    
  41. }
  42. }

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

這一題的完整詳解

核心觀念

本題考查兩種常見演算法:

  1. 二分搜尋法:將可能的整數答案範圍反覆折半,判斷是否存在整數平方根。
  2. 費波那契數列:利用迴圈逐項計算,並以兩個變數保存前兩項,避免遞迴呼叫。

(一)第 6~19 行程式碼功能

CSP4_1(int x) 用來判斷整數 xx 是否為非負整數的完全平方數,是則回傳 true,否則回傳 false。

解法使用二分搜尋法:

  • 若 x<0x<0,負數不可能是整數平方,直接回傳 false。
  • 對 x≥0x\geq 0,設定搜尋範圍 L=0L=0、R=xR=x。
  • 每次取中間值 M=L+⌊(R−L)/2⌋M=L+\lfloor(R-L)/2\rfloor,並計算 S=M2S=M^2。
  • 若 S=xS=x,表示找到整數平方根,回傳 true。
  • 若 S<xS<x,平方根在右側,令 L=M+1L=M+1。
  • 若 S>xS>x,平方根在左側,令 R=M−1R=M-1。
  • 範圍縮至空集合仍未找到時,回傳 false。

第 13 行先將 M 轉成 long 再相乘,可避免兩個 int 相乘時發生整數溢位。

(二)第 20~31 行程式碼功能

CSP4_2(int n) 計算並回傳第 nn 項費波那契數列。數列定義為:

F0=0,F1=1,Fn=Fn−1+Fn−2(n≥2)F_0=0,\qquad F_1=1,\qquad F_n=F_{n-1}+F_{n-2}\quad(n\geq2)
🔒

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

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

免費註冊

其他考古題