下列程序段中,所有未有列出宣告 (declaration) 的變量,均假設已經適當地宣告。題目中的「整數」是指 32 位元有符號的變數 (Pascal:
longint, C:
int)。 假設所有程序都正確地編譯,且沒有使用任何編譯器選項(除 C 程序的"-o"選擇外) 。
格式 題目數 佔分
甲部 多項選擇題 25 25
乙部 填充題 6 (A-M) 26
總分 51
甲部 (25 分)
請為下列每題各選一個最適合的答案,然後把答案的字母 (A、B、C 或 D) 寫到答題紙對應的空格中。
答對得一分,答錯不扣分。
1. 一環狀手鍊串連 5 個珠子,每粒珠子只能是黑色或白色。問有多少種不同的手鍊?
旋轉或反射所得的手鍊視作同一手鍊。
A. 8 B. 10 C. 16 D. 20
2. 一個已排序的陣列和一個已排序的鏈表的差異為:
i. 可以對一個已排序的陣列進行二分檢索,已排序的鏈表則不能。
ii. 如須從中間刪除一個元素,一個已排序的陣列比已排序的鏈表通常需要較多時間。
iii. 若事前已知道所有元素,用陣列儲存比鏈表需要較多記憶體。
A. 只有 i
B. i 和 ii
C. ii 和 iii
D. 以上皆是
3. 如果只有一個正確選項,哪個是正確?
A. 選項 C 是正確的。
B. 選項 A 是錯誤的。
C. 選項 B 是錯誤的。
D. 假如選項 A 是錯誤的,則選項 D 是正確的。
4. 以下程序的輸出是甚麼?
Pascal 版本
type node = record
x:array[1..20] of longint;
y:array[1..40] of char;
end;
var
a:array[1..1000] of longint;
b:array[1..250,1..10] of char;
c:array[1..100] of node;
begin
write(sizeof(a)+sizeof(b)+sizeof(c));
end.
C 版本
#include <stdio.h>
typedef struct { int x[20];
char y[40];
} node;
int a[1000];
char b[250][10];
node c[100];
int main() {
printf("%d",sizeof(a)+sizeof(b)+sizeof(c));
return 0;
}
A. 1110 B. 3600 C. 9500 D. 18500
5. 以下程序的輸出是甚麼?
Pascal 版本
var x, i: longint;
begin
x := 727650;
i := 1;
while (i < x) do begin
if (x mod i = 0) then x := x div i;
i := i + 1;
end;
write(x);
C 版本
#include <stdio.h>
int x, i;
int main() { x = 727650;
i = 1;
while ( i < x ) { if (x % i == 0) x = x / i;
i = i + 1;
}
printf("%d", x);
6. 過三關是一種二人遊戲。每位玩家輪流於 3x3 的方格上畫上 'O' 或 'X'。第一位玩家先選擇一個空 格填上 'O',然後第二位玩家選擇另一個空格填上 'X',如此類推,直至填滿所有格子。假如某個玩 家能夠把三個同樣的符號 ('O' 或 'X') 排成橫線、直線或對角線,即是勝者。如果兩個玩家都不能 做到的話,則打成平手。
已知兩個玩家不願意輸。以下哪種情況會打成平手?
i.
X O ii.
X
O
A. 只有 i B. 只有 ii C. i 和 ii D. 以上皆否
7. 甲在乙的前面,乙在丙的前面,丙在丁的前面。
甲和丙之間的距離必須小於或等於 5 米。
乙和丁之間的距離必須小於或等於 9 米。
乙和丙之間的距離必須大於或等於 3 米。
甲和丁之間的最大距離是多少?
A. 7 B. 8 C. 11 D. 17
8. 下述表達式共有多少可能的不同結果?
Pascal 版本
random(1011)*2-random(2013)
C 版本
(rand()%1011)*2-rand()%2013
A. 3022
B. 3023
C. 3024
D. 以上皆否
9. 假設
(m1, d1)及
(m2, d2)為同一年的不同日子。
m1,
m2為月份 (1-12) ,而
d1and
d2為日子 (1-31)。假設
(m1,d1)及
(m2,d2)均為有效日子。
k*m1+d1 < k*m2+d2
當
(m1,d1)早於
(m2,d2)時,上述表達式為真,否則為假,那麼以下哪個範圍包含
k的最小可 能值?
A. [29.50, 30.00]
B. (30.00, 30.50]
C. (30.50, 31.00]
D. (31.00, 32.00]
10. 以下函數
f()會的傳回值為?
Pascal 版本
function f:longint;
var i,k:longint;
begin k := 2;
for i:=1 to 2013 do if (i mod k = 0) then k := k*k;
f := k;
end;
C 版本 int f() { int i, k = 2;
for (i=1; i<=2013; ++i) if (i % k == 0)
k = k*k;
return k;
}
A. 1024
B. 2048
C. 32768
D. 65536
11. 以下程序的輸出是甚麼?
Pascal 版本 var
a:array[0..7] of longint =
(4,7,1,6,2,8,3,5);
x,ans,i,j,t:longint;
begin x:=4;
for i:=0 to x-1 do for j:=1 to 7-i do begin
if (a[j-1] > a[j]) then begin
t := a[j-1];
a[j-1] := a[j];
a[j] := t;
end;
ans:=a[j];
end;
write(ans);
end.
C 版本
#include <stdio.h>
int a[8] = {4,7,1,6,2,8,3,5};
int x=4, ans=-1, i, j, t;
int main() {
for (i=0; i<x; ++i) for (j=1; j<8-i; ++j) { if (a[j-1] > a[j]) { t = a[j-1];
a[j-1] = a[j];
a[j] = t;
}
ans = a[j];
}
printf("%d", ans);
return 0;
}
A. 3 B. 4 C. 5 D. 6
12. X, Y, Z 分別專門生產 wineX, wineY 和 wineZ 三種酒,他們研究出一個能使他們公平地交易酒的 辦法,即是,任意一人收到的酒的總價值將等於他給予其餘二人的總價值。
假設 X 保留了一半 wineX,再將四分一給予 Y 及四分一給予 Z, Y 平均分配他的酒給所有人,
即是每人有三分一 wineY, Z 把一半的 wineZ 給予 X,再把剩下的平均分給自己和 Y 。 下表總括了交易後每人手上的酒:
wineX wineY wineZ X 1/2 1/3 1/2 Y 1/4 1/3 1/4 Z 1/4 1/3 1/4
若 wineZ 值三千元,那麼 wineX 和 wineY 分別值多少?(單位:千元)
A. wineX: 3 wineY: 4
B. wineX: 4 wineY: 3
C. wineX: 5 wineY: 3
D. wineX: 6 wineY: 3
對於題目 13-14,細閱以下程序:
Pascal 版本 var
i,sum : longint;
a,b:array[1..8] of longint;
function sum5(start:longint):longint;
begin
sum := 0;
for i := start to start+4 do sum := sum+a[i];
sum5 := sum;
end;
begin
a[1]:=4; a[2]:=2; a[3]:=9; a[4]:=10;
a[5]:=1; a[6]:=3; a[7]:=7; a[8]:=5;
fillchar(b,36,0);
for i := 1 to 4 do begin sum:=sum5(i);
b[i]:=sum;
end;
end.
C 版本
#include <stdio.h>
#include <string.h>
int i,sum;
int a[9], b[9];
int sum5(int start) { sum = 0;
for (i=start; i<start+5; i++) sum+=a[i];
return sum;
}
int main() {
a[1]=4; a[2]=2; a[3]=9; a[4]=10;
a[5]=1; a[6]=3; a[7]=7; a[8]=5;
memset(b,0,36);
for (i=1; i<=4; i++) { sum=sum5(i);
b[i]=sum;
}
return 0;
}
13. 程序退出前,
b[1]的值是多少?
A. 25 B. 26 C. 30 D. 以上皆否
14. 程序退出前,
b中最大值是多少?
A. 25
B. 26
C. 30
D. 以上皆否
i.
ii.
iii.
i.
ii.
iii.
15. 假設有以下的關係:
i. 如果今天是陰天,小明會感到傷心。
ii. 如果小明感到傷心,他會整天打電腦遊戲。
iii. 如果小明整天打電腦遊戲,他會在晚飯時大吃一頓。
你知道小明今天整天打電腦遊戲,那麼以下那條陳述可為真?
A. 今天是陰天。
B. 小明感到傷心。
C. 小明在晚飯時大吃一頓。
D. 以上皆是
16. 以下哪段程序段不會退出?
Pascal 版本 a:=2013;
while (a>0) inc(a);
b:=2013.0;
while (b<>0.0) b:=b-0.5;
c:=2013.0;
while (c<>0.0) c:=c-0.1;
C 版本 a=2013;
while (a>0) ++a;
b=2013.0;
while (b!=0.0) b=b-0.5;
c=2013.0;
while (c!=0.0) c=c-0.1;
A. 只有 i
B. 只有 ii
C. 只有 iii
D. ii 和 iii
對於題目 17-19,細閱以下程序段:
Pascal 版本
procedure P1(n:longint);
var i,j,k:longint;
begin
for i:=0 to n-1 do for j:=i+1 to n-1 do for k:=j+1 to n-1 do write('*');
end;
procedure P2(n:longint);
var i,j:longint;
begin
for i:=0 to n-1 do for j:=0 to n-1 do write('*');
end;
procedure P3(n:longint);
var i:longint;
begin
if (n >= 1) then begin
for i:=0 to n-1 do write('*');
P3(n div 2);
P3(n div 2);
end;
end;
procedure P4(n:longint);
begin
if (n >= 5) then begin
write('*');
P4(n-1);
P4(n-1);
end;
end;
C 版本
void P1(int n){
int i,j,k;
for (i=0; i<n; i++) for (j=i+1; j<n; j++) for (k=j+1; k<n; k++) printf("*");
}
void P2(int n){
int i,j;
for (i=0; i<n; i++) for (j=0; j<n; j++) printf("*");
}
void P3(int n){
int i;
if (n >= 1){
for (i=0; i<n; i++) printf("*");
P3(n/2);
P3(n/2);
} }
void P4(int n){
if (n >= 5){
printf("*");
P4(n-1);
P4(n-1);
} }
17. 考慮
P1(4)、
P2(4)、
P3(4)及
P4(4),哪一個函數會輸出最多數量的 '
*'?
A. P1
B. P2
C. P3
D. P4
18. 考慮
P1(9)、
P2(9)、
P3(9)及
P4(9),哪一個函數會輸出最多數量的 '
*'?
A. P1 B. P2 C. P3 D. P4
19. 假設
P4(n)輸出的 '
*' 都比
P1(n)、
P2(n)和
P3(n)多,以下哪個是
n的最小可能值?
A. 10 B. 11 C. 12 D. 不存在 n
20. 考慮以下程序。如果程序輸出 5 個'
*',哪一項不可能是陣列
a的初始值?
Pascal 版本
var x,k,i:longint;
a:array[0..7] of longint;
begin
// 這裡初始化陣列 a x:=0; k:=1;
for i:=0 to 7 do begin
if (a[i] * k > x * k) then begin
write('*');
x:=a[i];
k:=-k;
end;
end;
end.
C 版本
#include <stdio.h>
int x, k, i;
int a[8];
int main() { // 這裡初始化陣列 a x = 0, k = 1;
for (i=0; i<8; ++i) { if (a[i] * k > x * k) { printf("*");
x = a[i];
k = -k;
} }
return 0;
}
A. -1, 2, 3, -5, -1, 3, -3, -1
B. -1, 2, -1, -5, -1, 3, -3, 0
C. 1, -2, -7, -5, -1, -3, -3, -1
D. 1, -2, 7, -5, 1, -3, -3, -1
21. 設
swap(x,y)為一個可把
x和
y的數值互換的函數,以下程序段的輸出是甚麼?
Pascal 版本
var k,i:longint;
a: array[0..4] of longint;
procedure f(m:longint);
var i:longint;
begin
if (m=0) then begin
k:=k+a[0];
exit;
end else begin
for i:=0 to m-1 do begin
swap(a[i],a[m-1]);
f(m-1);
swap(a[i],a[m-1]);
end;
end;
end;
begin
for i:=0 to 4 do a[i]:=i;
k:=0;
f(5);
writeln(k);
end.
C 版本 int k,i;
int a[5];
void f(int m){
int i;
if (m==0) { k=k+a[0];
return;
} else {
for (i=0; i<m; i++) { swap(a[i],a[m-1]);
f(m-1);
swap(a[i],a[m-1]);
} } }
int main(){
for (i=0; i<5; i++) a[i]=i;
k=0;
f(5);
printf("%d\n",k);
return 0;
}
A. 0 B. 120 C. 240 D. 360
22. 有多少種方法塗黑三個小格,使得沒有兩個黑色小格在同一行?
23. 以下程序的輸出是甚麼?
Pascal 版本
var ans,i:longint;
function f(n:longint):longint;
var cnt,k:longint;
begin cnt:=0;
k:=1;
while (k<=n) do begin
if (k and n > 0) then cnt:=cnt+1;
k:=k*2;
end;
f:=cnt;
end;
begin ans:=0;
for i:=0 to 31 do ans:=ans+f(i);
writeln(ans);
end.
C 版本
#include <stdio.h>
int ans, i;
int f(int n){
int cnt,k;
cnt=0;
k=1;
while (k<=n){
if (k&n > 0) ++cnt;
k*=2;
}
return cnt;
}
int main(){
ans=0;
for (i=0; i<32; i++) ans+=f(i);
printf("%d\n",ans);
return 0;
}
A. 32 B. 80 C. 96 D. 160
24. 現在有一些道路連接著一些城市,每一條道路連接著兩個城市,它們都有不同的長度(沒有兩條道 路有相同的長度) ,人們只能經過道路從一城市到另一城市。對於任何兩個城市,它們之間最多有一 條道路連接著。
你要從城市甲走到城市乙,為了令路徑最短化,你計劃走過連接著城市甲和丙的道路,然後走過連 接城市丙和乙的道路(沒有其他更短的路徑)。
以下哪些陳述必定正確?
A. 如果禁止經過城市丙,你要走更長的距離。
B. 如果縮短連接城市甲和丙的道路,則你所選擇的道路會是唯一的最短路(即其他路徑更長)。
C. 如果增長連接城市甲和丙的道路使得這道路成為最長的道路,則你所選擇的路徑不再是最短路。
D. 如果有一道路連接城市甲和乙,則它的長度最少兩倍於最短道路的長度。
25. 細閱以下函數:
Pascal 版本
function f(n:longint):longint;
var ans,i:longint;
begin ans:=n;
for i:=2 to n do begin
if (n mod i = 0) then ans:=ans div i*(i-1);
while (n mod i = 0) do n:=n div i;
end;
f:=ans;
end;
C 版本
int f(int n){
int ans,i;
ans=n;
for (i=2; i<=n; i++){
if (n%i==0)
ans=ans/i*(i-1);
while (n%i==0) n/=i;
}
return ans;
}
以下哪一個輸入
n能產生最大的
f(n)?
A. 997 B. 1001 C. 1024 D. 1089
甲部完
乙部 (26 分)
下列各空格分別命名為 A 至 M,請在答題紙上對應的地方填上答案。
除非另外註明,否則答對得兩分,答錯不扣分。
注意:
(1) 答案不可以包括 C 語言的 ?: 運算元。
(2) 除非適當的函數庫已被引用,否則答案不可以包括任何函數庫內的函數。
(3) 答題紙上每個小格只可填上一個字符。
(4) 答案長度不得多於該題提供的小格數目。
1. 設 x 是 17 的正倍數且僅含數位'1'。問 x 的最小值有多少數位?
A
2.
上圖為一個有四間房子的村莊的地圖。
房子和道路可以經過任意(含 0)次。
長度為 3 的路徑例子為有 H→K→O→I 和 K→I→O→I。
留意 H→K→O→I, H→O→K→I 及 I→O→K→H 為不同路徑。
長度為 3 的不同路徑總數為 B 。
長度為 6 的不同路徑總數為 C 。
3. 假設棧
s中存在任意數量整數而棧
r為空。
你可以對棧執行以下操作:
push(a, x)
把整數
x壓入棧
apop(a)
把一個整數彈出棧
a並返回該數值
peek(a)返回棧
a的最頂數值
empty(a)
當棧
a為空時返回 真,當其他情況返回 假
以下程序令棧
r儲存棧
s的原有元素並由底至頂按升序排序,請完成程序段。
Pascal 版本
while not empty(s) do begin
tmp := pop(s);
while (not empty(r)) and ( D >tmp) do begin
push( E );
end;
push(r,tmp);
end;
C 版本
while (!empty(s)){
tmp = pop(s);
while (!empty(r) && D >tmp) { push( E );
}
push(r,tmp);
}
4. 考慮以下程序:
Pascal 版本 10 var
11 x1,y1,x2,y2:longint;
12 function dist(x1,y1,x2,y2:longint):longint;
13 begin
14 dist:=trunc(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
15 end;
16 begin
17 readln(x1,y1,x2,y2);
18 if (dist(x1,y1,x2,y2)<1) then
19 writeln('The distance is less than 1') 20 else if (dist(x1,y1,x2,y2)=1) then 21 writeln('The distance is 1') 22 else
23 writeln('The distance is greater than 1');
24 end.
C 版本
50 #include <stdio.h>
51 #include <math.h>
52 int x1,y1,x2,y2;
53 int dist(int x1, int y1, int x2, int y2) {
54 return floor(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
55 }
56 int main() {
57 scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
58 if (dist(x1,y1,x2,y2)<1)
59 printf("The distance is less than 1\n");
60 else if (dist(x1,y1,x2,y2)==1) 61 printf("The distance is 1\n");
62 else
63 printf("The distance is greater than 1\n");
64 return 0;
65 }
以上程序檢查兩點座標
(x1,y1),
(x2,y2)之間的距離為小於、等於、或大於 1。 你可以假設
x1,y1,x2和
y2 為[-10000,10000] 內的整數。可是,這程序有一邏輯錯誤,但只要更改其中一行便可修正。找出 該行及然後重寫。
行數: F 重寫: G
注(C 版本):
y1在
<math.h>中被定義為 double y1(double)。
對於這題,請假設無此定義。如有不明白之處,忽略即可。
5. 假設陣列
a(Pascal:
a[0..n-1], C:
a[n]) 是由不一樣的正整數組成。
max(i,j)傳回
a[i]和
a[j]之間(含
a[i]和
a[j])的最大值。
以下程序段搜尋陣列
a中第二大的值。請完成程序段。
Pascal 版本
maximum := max(0, n-1);
i := 0; j := n-1;
while (j>i) do begin
k := H ;
if ( I = maximum) then j := k
else
i := k+1;
end;
a[i] := -a[i];
secondmaximum := J ; a[i] := -a[i];
C 版本
maximum = max(0, n-1);
i = 0; j = n-1;
while (j>i) {
k = H ;
if ( I == maximum) j = k;
else i = k+1;
}
a[i] = -a[i];
secondmaximum = J ; a[i] = -a[i];