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

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

第 一 題25 分

下面的遞迴程式執行後,印出的信息為何?作答必須解釋計算過程,只寫答案而未加解釋,只能得部分分數。

#include <stdio.h>

int new1(int p) { if (p > 90) return(new1(new1(p - 11))); return(p - 10); }

int new2(int p) { if (p < 91) return(new2(p + 11)); return(p); }

int new(int p) { return(new1(new2(p))); }

int main(int argc, char **argv) { int q;

q = 65;
printf("new(%d)= %d.\n", q, new(q));

q = 95;
printf("new(%d)= %d.\n", q, new(q));

q = 100;
printf("new(%d)= %d.\n", q, new(q));

q = 104;
printf("new(%d)= %d.\n", q, new(q));

q = 110;
printf("new(%d)= %d.\n", q, new(q));

return(0);

}

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

這一題的完整詳解

核心觀念

本題考查遞迴函式的呼叫順序,以及依照 if 條件逐層追蹤回傳值。

  • new2(p):若 p<91p<91,就以 p+11p+11 再呼叫自己;直到參數至少為 9191 才回傳。
  • new1(p):若 p>90p>90,就先計算 new1(p - 11),再把該結果當作參數呼叫 new1;若 p≤90p\le 90,則回傳 p−10p-10。
  • new(p):先計算 new2(p),再將結果傳入 new1。

解題方法

先求 new2(p) 的結果。當 p<91p<91 時,每次增加 1111,直到參數達到或超過 9191;因此 new2 的回傳值是第一個不小於 9191 的數。

接著令此回傳值為 rr,追蹤 new1(r)。當參數大於 9090 時,先減 1111 遞迴呼叫,再將內層結果作為外層的新參數;直到遇到不大於 9090 的參數,回傳該參數減 1010。

計算過程

q=65q=65

new2 的參數依序為:

65→76→87→9865\to76\to87\to98

因此 new2(65)=98。

new1 的呼叫順序為:

new1(98)=new1(new1(87))=new1(77)=67\begin{aligned} \text{new1}(98) &=\text{new1}(\text{new1}(87))\\ &=\text{new1}(77)\\ &=67 \end{aligned}

其中 new1(87)=87−10=77\text{new1}(87)=87-10=77,再由 new1(77)=77−10=67\text{new1}(77)=77-10=67。所以 new(65)=67。

q=95q=95

new2(95)=95,因為 95≥9195\ge91。

new1(95)=new1(new1(84))=new1(74)=64\begin{aligned} \text{new1}(95) &=\text{new1}(\text{new1}(84))\\ &=\text{new1}(74)\\ &=64 \end{aligned}

所以 new(95)=64。

q=100q=100

new2(100)=100。

🔒

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

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

免費註冊

第 二 題25 分

請參考以下 Java 程式。如果第一個輸入是 2525,第二個輸入是 −34-34(負 3434),最後印出來是什麼?作答必須解釋計算過程,只寫答案而未加解釋,只能得部分分數。

import java.util.Scanner;

public class JavaExample { public static void main(String args[]) { int num1, num2; Scanner scanner = new Scanner(System.in);

    System.out.print("Enter first number:");
    num1 = scanner.nextInt();

    System.out.print("Enter second number:");
    num2 = scanner.nextInt();

    num1 = num1 ^ num2;
    num2 = num1 ^ num2;
    num1 = num1 ^ num2;

    scanner.close();

    System.out.println("The First number is " + num1);
    System.out.println("The Second number is " + num2);
}

}

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

這一題的完整詳解

核心觀念

本題考查 Java 的位元 XOR(互斥或)運算,以及如何用 XOR 交換兩個整數的值。對每一個二進位位元,XOR 的規則是:

位元 A位元 BAXORBA \mathbin{\text{XOR}} B
000
011
101
110

因此,AXORA=0A \mathbin{\text{XOR}} A=0,且 AXOR0=AA \mathbin{\text{XOR}} 0=A。Java 的 ^ 是整數位元 XOR 運算子。

解題方法

設輸入後 num1 = 25、num2 = -34。程式依序執行三次 XOR 指派:

  1. num1 = num1 ^ num2

此時 num1 = 25 ^ (-34),num2 仍為 −34-34。

  1. num2 = num1 ^ num2

將第一步的 num1 代入:

=25\mathbin{\text{XOR}}\bigl((-34)\mathbin{\text{XOR}}(-34)\bigr) =25\mathbin{\text{XOR}}0 =25$$
🔒

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

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

免費註冊

第 三 題25 分

請問下列程式執行後,印出結果為何?作答必須解釋計算過程,只寫答案而未加解釋,只能得部分分數。

(define return #f)

(+ 1 (call/cc [lambda(cont) (set! return cont) 1] ))

(return 22)

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

這一題的完整詳解

核心觀念

本題考查 Scheme 的 續延(continuation),尤其是 call/cc(call-with-current-continuation)如何捕捉程式在呼叫當下「接下來要做什麼」。

call/cc 會將目前的續延傳給它的程序參數。本題中,cont 代表從 call/cc 返回後要繼續執行的部分。程式用 set! 將這個續延存入全域變數 return,之後便可呼叫 return,把執行流程帶回被捕捉的位置,並以呼叫時提供的值作為該位置的結果。

解題方法

先看外層加法:

(+ 1 (call/cc ...))

執行 call/cc 時,已經確定後續要做的事是:取得 call/cc 的結果,再將它與 1 相加。因此,捕捉到的 cont 可理解為:

把給定的值當作 call/cc 的結果,接著計算 (+ 1 給定的值)。

第一次執行 call/cc 時,傳入的程序執行:

(set! return cont)
1
🔒

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

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

免費註冊

第 四 題25 分

請問下列程式執行後,印出結果為何?作答必須解釋計算過程,只寫答案而未加解釋,只能得部分分數。

#include <iostream>

using namespace std;

bool sqst(int arr[], int n, int sum) { if (sum == 0) { return true; }

if (n < 0 || sum < 0) {
    return false;
}

bool include = sqst(arr, n - 1, sum - arr[n]);
bool exclude = sqst(arr, n - 1, sum);

return include || exclude;

}

int main() { int arr[] = { 7, 3, 2, 5, 8 }; int sum = 14; int n = sizeof(arr) / sizeof(arr[0]);

if (sqst(arr, n - 1, sum))
    cout << "Yes";
else
    cout << "No";

return 0;

}

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

這一題的完整詳解

核心觀念

sqst 使用遞迴判斷陣列中是否存在一組元素,其總和等於指定的 sum,這是「子集合總和問題」(Subset Sum)。

對每個元素都有兩種選擇:

  • 納入:將目前元素 arr[n] 加入子集合,因此遞迴計算 sum - arr[n]。
  • 排除:不使用目前元素,因此保留 sum 不變。

只要納入或排除的其中一條路徑能使目標總和歸零,就回傳 true。

解題方法

陣列為 {7, 3, 2, 5, 8},目標總和是 1414。n 從最後一個索引開始,初始值為 44。函式依序處理索引 44 至 00 的元素。

兩個終止條件是:

  • sum == 0:已找到總和,回傳 true。
  • n < 0 || sum < 0:元素已用完,或剩餘目標總和小於 00,回傳 false。

沿著「納入」分支,依序選取 88、55、22:

14−8=6,6−5=1,1−2=−114 - 8 = 6,\qquad 6 - 5 = 1,\qquad 1 - 2 = -1
🔒

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

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

免費註冊

其他考古題