2017年10月4日 星期三

APCS (大學程式先修檢測) 105 年 10 月觀念題解析

解完 105 年 3 月份 APCS 觀念題後感覺越來越上手了, 繼續來解 10 月份的觀念題.

1. 右側 F() 函式 執行 後,輸出 為何?

void F( ) {
  char t, item[] = {'2', '8', '3', '1','9'};
  int a, b, c, count = 5;

  for (a=0; a<count-1; a=a+1) {
    c = a;
    t = item[a];
    for (b=a+1; b<count; b=b+1) {
       if (item[b] < t) {
         c = b;
         t = item[b];
         }
       if ((a==2) && (b==3)) {
         printf ("%c %d\n", t, c);
         }
       }
    }
  }

(A) 1 2     (B) 1 3     (C) 3 2       (D) 3 3

解析 : 

此題乍看之下很複雜, 是雙重迴圈, 但實際上不需要從頭追蹤程式執行流程, 只要看它的輸出條件即可, 其唯一的輸出指令 printf() 會被執行的條件是外迴圈索引 a=2 且內迴圈索引 b=3 時, 只要追蹤此條件即可. 

外迴圈 a=2 時, c=2, t=item[2]=3
然後進入內迴圈, 只須看 b=3 時, 因 item[b=3]=1 小於外迴圈得到的 t=3, 因此 if 為真, 執行 c=b=3, 以及 t=item[b=3]=1, 接著判斷 a==2 且 b==3 都符合, 因此輸出 t,c 為 1 3, 答案為 (B).


2. 下列 switch 敘述程式碼可以如何以if-else  改寫?   

switch (x) {
  case 10: y = 'a'; break; 
  case 20:
  case 30: y = 'b'; break; 
  default: y = 'c';
  }

   (A) if (x==10) y = 'a' ;
       if (x==20 || x==30) y = 'b';
       y = 'c';

   (B) if (x==10) y = 'a' ; 
       else if (x==20 || x==30) y = 
       else y = 'c';

   (C) if (x==10) y = 'a' ; 
       if (x>=20 && x<=30) y = 'b';
       y = 'c';

   (D) if (x==10) y = 'a' ; 
       else if (x>=20 && x<=30) y = 'b';
       else y = 'c';

解析 : 

switch case 相當於 if else if else 架構, 不是 if if if 架構, 故 (A) 與 (C) 均排除. (B) 與 (D) 基本上相同, 差別在 else if 裡面兩個條件是 AND 還是 OR. 由於 case 20 是空的, 無 break 跳出, 若 x=20 會直接往下執行 case=30 選項, 因此 x=20 或 x=30 都是執行 x=30, 是 OR 關係, 答案是 (B).


3. 給定下列 G() , K() 兩函式,執行 G(3) 後所回傳的值為何 ?

int K(int a[], int n) {
  if (n >= 0)
    return (K(a, n-1) + a[n]); 
  else return 0;
  }
int G(int n){
  int a[] = {5,4,3,2,1}; 
  return K(a, n);
  }

(A) 5    (B) 12   (C) 14     (D) 15

解析 : 

此題是遞迴函數題, 追蹤如後 :

呼叫 G(3) : 把陣列 a 與 n=3 傳入呼叫 K(a,3)
呼叫 K(a,3) : 因 n=3 大於 0, 故回傳 K(a, n-1) + a[n]=K(a, 2) + a[3]=K(a,2)+2
呼叫 K(a,2) : 因 n=2 大於 0, 故回傳 K(a, n-1) + a[n]=K(a, 1) + a[2]=K(a,1)+3
呼叫 K(a,1) : 因 n=1 大於 0, 故回傳 K(a, n-1) + a[n]=K(a, 0) + a[1]=K(a,0)+4
呼叫 K(a,0) : 因 n=0 等於 0, 故回傳 K(a, n-1) + a[n]=K(a, -1) + a[0]=K(a,-1)+5
呼叫 K(a,-1) : 因 n=-1 小於 0, 故遞迴結束回傳 0, 一一傳回原呼叫者, 最後回傳的結果是 2+3+4+5=14, 答案是 (C)


4. 下列程式碼執行後輸出結果為何 ?

int a=2, b=3;
int c=4, d=5;
int val;
val = b/a + c/b + d/b;
printf ("%d\n", val);

(A) 3      (B) 4      (C) 5     (D) 6

解析 : 

C 語言的整數除法是無條件捨去 (只取整數), 因此 b/a + c/b + d/b=3/2+4/3+5/3=1+1+1=3, 答案是 (A).


5. 下列程式碼執行後輸出結果為何 ?

int a[9] = {l, 3, 5, 7, 9, 8, 6, 4, 2}; 
int n=9, tmp;

for (int i=0; i<n; i=i+1) {
  tmp = a[i];
  a[i] = a[n-i-1];
  a[n-i-1] = tmp;
  }                                        
for (int i=0; i<=n/2; i=i+1)
  printf ("%d %d ", a[i], a[n-i-1]);

(A) 2 4 6 8 9 7 5 3 1 9
(B) 1 3 5 7 9 2 4 6 8 9
(C) 1 2 3 4 5 6 7 8 9 9
(D) 2 4 6 8 5 1 3 7 9 9

解析 : 

此程式有兩個 for 迴圈, 第一個迴圈是以陣列元素 a[4]=9 為中心左右交換兩次, i=0~3 左右交換一次變成 a[]={2,4,6,8,9,7,5,3,1}, i=4 時 9 與 9 自己交換, i=5~8 時左右又交換一次還原, 變回原來的 a[]={1,3,5,7,8,9,8,6,4,2}, 等於是虛晃一招.

第二個迴圈拜訪陣列 i=0~9/2=0~4, 會印出 a[i] 與其以 a[4]=9 為軸, 從尾端算過來的對應元素, 例如 a[0] 對應 a[8], 印出 12, a[1] 對應 a[7] 印出 34, a[2] 對應 a[6] 印出 56, a[3] 對應 a[5] 印出 78, a[4] 對應 a[4] 印出 99, 整個輸出 1234567899, 故答案是 (C).


6. 右側函式以 F(7) 呼叫後回傳值 為 12,則<condition> 應為何 ?

int F(int a) {
  if ( <condition> )
    return 1;
  else
    return F(a-2) + F(a-3);

(A) a < 3
(B) a < 2
(C) a < 1
(D) a < 0

解析 : 

此為遞迴函數題, 求其終止條件為何才能讓呼叫 F(7) 得到回傳值 12.

若條件為 a < 3 :
F(7)=F(5)+F(4)=3+2=5 (非也)
F(5)=F(3)+F(2)=2+1=3
F(4)=F(2)+F(1)=1+1=2
F(3)=F(1)+F(0)=1+1=2

若條件為 a < 2 :
F(7)=F(5)+F(4)=4+3=7 (非也)
F(5)=F(3)+F(2)=2+2=4
F(4)=F(2)+F(1)=2+1=3
F(3)=F(1)+F(0)=1+1=2
F(2)=F(0)+F(-1)=1+1=2

若條件為 a < 1 :
F(7)=F(5)+F(4)=5+4=9 (非也)
F(5)=F(3)+F(2)=3+2=5
F(4)=F(2)+F(1)=2+2=4
F(3)=F(1)+F(0)=2+1=3
F(2)=F(0)+F(-1)=1+1=2
F(1)=F(-1)+F(-2)=1+1=2

若條件為 a < 0 :
F(7)=F(5)+F(4)=7+5=12 (正確)
F(5)=F(3)+F(2)=4+3=7
F(4)=F(2)+F(1)=3+2=5
F(3)=F(1)+F(0)=2+2=4
F(2)=F(0)+F(-1)=2+1=3
F(1)=F(-1)+F(-2)=1+1=2
F(0)=F(-2)+F(-3)=1+1=2

故答案為 (D)


7. 若 n為正整數,下列程式三個迴圈執行完畢後 a 值將為何 ?

for (int i=1; i<=n; i=i+1)
  for (int j=i; j<=n; j=j+1)
    for (int k=1; k<=n; k=k+1)
      a = a + 1;

(A) n(n+1)/2
(B) n3/2
(C) n(n-1)/2
(D) n2(n+1)/2

解析 : 





9. 下列是依據分數 s 評定等第的程式碼片段,正確的等第公式應為:

90~100 判為 A 等
80~89 判為 B 等
70~79 判為 C 等
60~69 判為 D 等
0~59 判為 F 等



這段程式碼 在處理 0~100 的分數時,有幾個分數的等第是錯?

(A) 20    (B) 11     (C) 2   (D) 10



~未完待續~

7 則留言 :

Unknown 提到...

請問105年10月APCS會繼續解題嗎??還有106年3月試題.....真的是很難的題目,請大師協助
感恩.

小狐狸事務所 提到...

因事務繁忙暫停, 只要有空就會繼續解, 我自己也是邊學邊寫留下足跡, 談不上大師啦!

匿名 提到...

請問可以用數字計算幫忙解第7題嗎?我程式執行出來是n^3 謝謝您!

小狐狸事務所 提到...

Sorry 最近蠻忙的, 要找時間看看!

提到...

對要考APCS的人,真得很有幫助…希望能繼續寫下去~~~支持

匿名 提到...

抱歉冒昧問遺下,還會繼續解嗎

小狐狸事務所 提到...

Hi, 我很想把它寫完, 但時間實在有限啊! 不過前陣子在書局好像有看到 APCS 的解題書, 可去找看看.