第1题(14分)以下程序是将一组整数按从小到大的顺序排列。排序的方法是将长度为n的数a分为两个长度分别为(n div 2)与(n-n div 2)的子数组a1,a2。然后递归调用排序过程,将a1,a2分别排序,最后将a1,a2归并成数组a。例如a=(3,1,2,4),那么a1=(3,1),a2=(2,4)。调用排序过程将a1,a2排序,得到a1=(1,3),a2=(2,4),然后进行合并排序。 从键盘输入数的长度n以及n个整数,存在数组a中,调用子过程sort进行排序,最后输出排序结果。 program wsh;
const maxn=100;.
type arr:array[1..maxn] of integer;
var
a:array[1..maxn] of integer;
n,i:integer;
procedure sort(n:integer; var a:arr);
var
i, p1, p2, n1, n2: integer;
a1,a2 :arr;
begin
if n = 1 then exit;
fillchar(a1,sizeof(a1) ,0);
fillchar(a2,sizeof(a2) ,0);
n1:=0; n2:=0;
n1:=n div 2; n2:=(____(1)____);
for i:= 1 to n1 do a1[i]:=a[i];
for i:= 1 to n2 do a2[i]:=____(2)____;
____(3)____;
sort(n2, a2);
p1:=1; p2:=1;
n:=0;
while (p1 <= n1) and (____(4)____) do
begin
n:=n+1;
if ____(5)____
then begin a[n]:=a1[p1] ;inc(p1); end
else begin ____(6)____; inc(p2) ;end;
end;
if p1 <= n1
then for i:= ____(7)____ to n1 do begin n:=n+1;a[n]:=a1[i] end
else for i:=p2 to n2 do begin n:=n+1; a[n]:=a2[i]; end;
end;
begin
write('n = ');
readln (n);
for i:= 1 to n do read(a[i]);
readln;
sort(n,a);
for i:=1 to n do write(a[i],'');
writeln;
end. 答案:n-n1
a[n1+i]
sort(n1,a1)
(p2 < =n2)
a1[p1] < a2[p2]
a[n]:=a2[p2]
p1
第2题(8分)有n(1≤n≤100)个同学种m(1≤n≤m≤100)种小树苗,例如:4个同学(1、2、3、4)每小时种4种树苗(A、B、C、D)的数量估算如下表所示,编程输出每人种1种苗所用的总时间最少的安排方案和所花费的时间。 学 生 A B C D
1 5 2 4 5
2 4 3 5 3
3 5 2 4 2
4 3 2 3 3
program wsh;
const
maxn=100; maxm = 100;
var
a: array[1..maxn, 1..maxm] of integer;
m, n: integer;
i, j, t: integer;
procedure work(k,t1: integer);
var i: integer;
begin
if ____(1)____ then
begin
if t1 < t then t1:=t;
exit;
end;
for i:= ___(2)___ to ___(3)___ do
work(k+1,___(4)___);
end;
begin
readln(n,m);
for i:=1 to n do
begin
for j:=1 to m do read (a[i,j]);
readln
end;
t:= maxint;
work(1,0);
writeln(t)
end. 答案:k>n
1
m
t1+t[k,i]
第3题(10分)程序的任务是用0…9中的数字填入如下乘法运算的*处,数字可重复使用,且所用的数字至少有一个是素数,要求输出满足下列算式的方案数。 * * *
x * *
----------------
* * *
* * *
----------------
* * *
program wsh;
const p:set of 0...9 = [2,3,5,7];
var
s:set of 0..9;
n: integer;
ans: longint;
f: text;
procedure init;
var
i: integer;
t:byte;
begin
readln(n);
s:=[];
for i:=1 to n do
begin
read(t);
s:=s+[t];
end;
close(f);
end;
function ok(x,l:integer):boolean; {此函数判断x是否符合条件}
var t: byte;
begin
ok:=false;
if ___(1)___< > l then exit;
while x< >0 do
begin
t:=x mod 10;
if not ( t in s) then exit;
x:=x div 10;
end;
ok:=true;
end;
function inset(x:integer):boolean; {此函数判断x中是否包含素数字}
var t: byte;
begin
inset:= false;
while ___(2)___ do
begin
t:=x mod 10;
if t in p then
begin
inset:= true;
exit;
end;
___(3)___;
end;
end;
procedure work;
var i,i1,i2,i3,j1,j2:integer;
begin
ans:=0;
for i1:=1 to 9 do
if i1 in s then
for i2:=1 to 9 do
if i2 in s then
for i3:=1 to 9 do
if i3 in s then
begin
___(4)___;
for j1:=1 to 9 do
if (j1 in s) and ok(j1*i,3) then
for j2:=1 to 9 do
if (j2 in s) and ok(j2*i,3) and ___(5)___ then
begin
if (i1 in p) or (i2 in p) or (i3 in p)
or (j1 in p) or (j2 in p) or inset(j1*i) or inset(j2*i)
then inc(ans);
end;
end;
writeln(ans);
end;
begin
init;
work;
end. 答案:trunc(ln(x)/ln(10))+1
x>0
x:=x div 10
i:=i1*100+i2*10+i3
ok(j1*i*10+j2*i,4)
第4题(15分)下列程序是对冒泡排序的一种改进,数组elem中有n个元素elem[1]、elem[2]…、elem[n]。要排序的关键字是key。先从一端开始扫描,进行比较、交换,然后改变下一趟的扫描方向进行同样的处理。请完善下面的过程。program wsh;
type
Td = record
key: integer;
inf: real;
end;
var
elem:array[1..1000] of Td;
n, i: integer;
procedure shakesort(n: integer);
var
i, t, h: integer;
c: boolean;
temp: Td;
begin
h:=1;
t:=n;
repeat
____(1)____;
for i:=h to t-1 do
if elem[i].key > elem[i+1].key then begin
temp:=elem[i];
elem[i]:=elem[i+1];
elem[i+1]:=temp;
____(2)____;
end;
____(3)____;
for i:=t-1 downto h do
if elem[i].key > elem[i+1].key then begin
temp:=elem[i];
elem[i]:=elem[i+1];
elem[i+1]:=temp;
____(4)____;
end ;
____(5)____;
until c ;
end;
begin{主过程}
…{略}
end. 答案:c:=true
c:=false
t:=t-1
c:=false
h:=h+1
第5题(15分)读入一个10x10的数字矩阵,矩阵中的数字各不相同,输出这个矩阵经过旋转、翻转后的7种不同样式。program wsh;
var
matrix: array [0..7,1..10,1..10] of integer;
lr, lc, which: integer;
procedure overturn( which: integer);
var
lr, lc: integer;
begin
for lr:= 1 to 10 do
for lc:= 1 to 10 do
matrix[which,lr,lc]:=matrix[which-1,___(1)___,___(2)___];
end;
procedure rotate( which: integer);
var
lr, lc: integer;
begin
for lr:=1 to 10 do
for lc:=1 to 10 do
matrix[which,lr,lc]:=matrix[which-1,___(3)___,___(4)___];
end;
begin
for lr:= 1 to 10 do
for lc:=1 to 10 do
read(matrix[0,lr,lc]);
readln;
for which:= 1 to 7 do
begin
if ___(5)___ then overturn(which)
else rotate(which);
for lr:=1 to 10 do
begin
for lc:= 1 to 10 do
write(matrix[which,lr,lc]:3);
writeln;
end;
readln;
end;
end. 答案:11-lr
lc
11-lc
lr
which=4
第6题(16分)[问题描述]在n个元素的集合S中,找最大和最小元素(设n的值为2m). [解题思路]把集合S分成两个子集S1和S2,每个子集有n/2个元素.应用递归过程search(S,Y,MAX,MIN)(S中有2k个元素),过程返回一对(MAX,MIN)值,为最大和最小元素,最后,把S1和S2中的最大和最小元素进行比较,从而得到S中的最大和最小元素. [程序]program wsh;
type data = array[1..256] of byte;
jh = set of byte;
var s,ss:jh;
a:data;
i ,j, d,largest, smallest: byte;
function sq(k: byte): byte;
begin
if k =1 then sq:=2 else sq:=2*sq(k-1);
end;
procedure seareh(x:jh; y:byte; var max,rain:byte);
var k,p,w,nxl,nx2,ni1,ni2,n: byte;
m:array[1..2] of byte;
s1 ,s2:jh;
begin
if y = 2 then
begin
p:=0;
for k:=1 to i do
if ___(1)___ then
begin
p:=p+1;m[p]:=___(2)___;
end;
if ___(3)___ then
begin
w:=m[1];m[1]:=m[2];m[2]:=w;
end;
max:= m[1] ;min:= m[2] ;exit;
end
else
begin
si:=[];n:=O;y:=___(4)___;
for k:=1 to i do
if ___(5)___ then
begin
n:=n+1;if n <= y then s1:=___(6)___;
end;
s2:=___(7)___;
search(s1,y,nx1,ni1);search(s2,y,nx2,ni2);
if nx1 > nx2 then max:=nx1 else max:=nx2;
if ni1 < ni2 then min:=ni1 else min:=ni2;
end
end;
begin
i:=0;s:=[];ss:=[];
for j:=1 to 7 do ss:=ss+[sq(j)];
writeln('enter 2^n data:');
repeat
while not eoln do
begin
i:=i + 1; read(d);
if ___(8)___ then i:= i - 1
else begin
a[i]:=d;s:=s+[a[i]];
end;
end; readln;
until i in ss;
search(s,i,largest,smallest);
writeln('largest-data:',largest,'smallest-data:',smallest)
end. 答案:a[k] in x
m[p]:=a[k]
m[1] < =m[2]
y:=trunc(y/2)
a[k] in x
s1:=s1+[a[k]]
s2:=x-s1
d in s
第7题(14分)[问题描述]将一个含有运算符为:(、)、+、-、*、/、^(乘幂运算)、~(求负运算)的中缀表达式,如:((1+2)*5)^2-(3+5)/2转化为后缀表达式,如:12+5*2^35+2/-. [解题思路]将中缀表达式转化为后缀表达式,首先规定运算符的优先数如下:┌───┬───┬───┬─────┬──────┬───┬───┐
│运算符│ ( │ ) │ +,- │ * ,/ │ ~ │ ~ │
├───┼───┼───┼─────┼──────┼───┼───┤
│优先数│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │
└───┴───┴───┴─────┴──────┴───┴───┘ 1.若输入是运算量,则将该运算量输出; 2.若是左括号“(”,则将该符号的优先数压入设置的运算符堆栈e[p]中去; 3.输入运算符优先数是2,3,4,5时,如果栈空,则将运算符的优先数进栈。如果栈不空,则将它与栈顶元素进行比较,倘若优先数大于栈顶元素的优先数,则进栈;小于顶元的,则顶元退栈并输出该运算符,然后再继续比较,直到大于顶元或栈空时进栈; 4.若是右括号“)”,同时栈顶元又为左括号“(”,则栈顶元退栈,并抹去右括号“)”.否则转3处理; 5.输入完而栈非空,则将栈内内容逐一退栈并输出。所有输出的结果就为后缀表达式。 过程中用到的相关数据结构如下:type arraydata = array[1..100] of string[20];
const fh:array[1..8] of string[1]
=('(',')','+','-','*','/','~','^');
b:array[1..8] of byte =(0,1,2,2,3,3,4,5);
var d: arraydata; {存储运算量及运算符号}
i,j,m,k: byte;
[过程程序]
procedure hzbds(var d: arraydata; var m: byte );
var: array [ 1'-. 100 ] of byte;
i,p,k ,bi:byte;
bl: boolean;
begin
p:=O;k:=1;bj:=0;
while k<=m do
begin
if ___(1)___ then
begin
p:=p+1;e[p]:=1
end
else begin
for i:=2 to 8 do
if ___(2)___ then
begin
b1:= true;
repeat
if ___(3)___ then
begin
p:= p+1 ;e[p]:=i;bj:= 1 ;b1:= false
end
else if ____(4)___ then
if e[p] < >1 then
begin
p:=p+1;e[p]:=i;bj:=1;b1:=false
end
else if d[k] < >')' then
begin
p:=p+1;e[p]:=i;bj:=1;b1:=false
end
else begin
___(5)___;bj:= 1 ;b1:= false;
end
else begin
write(fh[e[p]] ,' ') ;p:=p-1
end;
until b1 = false;
end
if ___(6)___ then write(d[k] ,' ') else bj:=0;
end;
k:=k+1
end
b1:= true;
repeat
if p=0 then b1:= false
else begin
___(7)___;p:=p-1;
end
until b1 = false;
writeln;
end; 答案:d[k]:='('
d[k]:=fh[i]
p=0
b[e[p]] < b[i]
p:=p-1
bj=0
write(fh[e[p]],'')
第8题(15分)以下程序完成对数组每个元素向后移动n个单位。数组元素的下标依次为0到m-1,对任意一个数组元素a[i]而言,它的值移动后将存储在数组元素a[(i+n) mod m]中。 例如,m=10,n=3,移动前数组中存储的数据如下前一行所示,则程序运行后数组中存储的数据如下后一行所示。 0 3 86 20 27 67 31 16 37 42
16 37 42 0 3 86 20 27 67 31
程序清单:
program wsh;
const maxm = 10000;
var i, k, m, n, rest, start, temp: longint;
a:array [0..maxm] of longint;
begin
write('input m, n: ');
readln(m ,n);
for i:=0 to m-1 do a[i]:= random(100);
writeln('before move');
for i:=0 to m -1 do write(a[i]:5);
writeln;
rest:= m; start:= 0;
while ___(1)___ do
begin
k:= start;
repeat
k:=(k+n) mod m
until k <= start;
if ___(2)___ then
begin
temp:= a[k];
repeat
a[k]:=a[(m*n+k-n) mod m];
k:=(m*n+k-n) mod m;
___(3)___;
until k = start;
___(4)___;
end;
___(5)___;
end;
writeln('after move');
for i:=0 to m - 1 do write(a[i]:5);
writeln
end. 答案:rest>0
k:=start
rest:=rest-1
a[(k+n) mod m]:=temp
start:=start+1
第9题(15分)设m叉树采用列表法表示,即每棵子树对应一个列表,表的结构为:子树根顶点的值部分(设为一个字符)和用“( )”括起来的各树的列表(如有子树的话),各子列表间用“,”分隔。例如下面的三叉树可用表a(b(c,d),e,f(g,h,i))表示。
本程序输入列表,生成一棵m叉树,并由m叉树输出列表。假定输入无错误。 程序清单: program wsh;
const m=3;
type pointer =^node;
node = record
val: char;
subtree: array [1..m] of pointer
end;
var
i: integer;
bur: string;
root: pointer;
procedure maketree(var s: pointer); {由列表生成m叉树}
var k: integer;
begin
___(1)___;
s^.val:= buf[i];
i:=i+1;
for k:=1 to m do s^.subtree[k]:=nil;
if buf[i]='(' then
begin
k:=1;
repeat
i:=i+1;
___(2)___;
if buf[i] =')' then
begin i:= i + 1; break end;
k:=k+1
until ___(3)___;
end
end;
procedure walktree(t:pointer); {由m叉树输出列表}
var i: integar;
begin
if t < > nil then
begin
___(4)___;
if t^.subtree[1] < > nil then
begin
write('(');
for i:=1 to m do
begin
___(5)___;
if (i< >m)and(t^.subtree[i+1] < >nil) then write(',')
end;
write(')')
end
end
end;
begin { main program }
write('input list: ');
readln(buf);
i:=1;
maketree(root);
walktree(root);
writeln
end. 答案:new(s)
maketree(s^.subtree[k])
buf[i] < >','
write(t^.val)
walktree(s^.subtree[i])
|