第三节 While
循环
While循环是当型循环。
[例3.8]
前面第一章[例1.2]的鸡兔同笼,头30,脚90,
求鸡兔各几只?在此用下面方法编程求解。
解:
设鸡为J只,兔为T只。已知头为H,
脚为F。
①让鸡的只数逐次加1进行递推计算,初始时J=0;
②计算兔的只数T=H-J;
③当总脚数(4*T+2*J) <
> F就做 (J=J+1,T=H-J);
④当4*T+2*J=F时,说明所推算的J和T是正确的,应结束循环,并输出T,
J。
Pascal程序:
Program Exam38;
Const H=30;
F=90;
Var J,T :
integer;
Begin
J:=0;
T:=H-J;
{初始时让J从0开始计算
}
While 4*T+2*J<>F
do {当条件为真就做do后面的循环体 }
begin
inc(J);
{
递推改变J值 }
T:=H-J
{计算兔的只数 }
end;
Writeln('T=',T,'
':6, 'J=', J ) ;
Readln
End.
程序中采用While当型循环,While循环语句的格式为:
While
条件式 do 语句;
其中do后面的“语句”是被重复执行的,称为循环体;若循环体是多个语句,
必须用begin--end包起来成为复合语句。
While循环首先判断条件式,当条件式的值为真就执行do
后面的语句(循环体)。
While的循环体内也必须包含能改变控制变量取值语句,
影响条件式的值,
最终使条件式为false (假),
才能结束循环。
[例3.9]
输入任一的自然数A, B, 求A
, B的最小公倍数。
解:这里采用适合计算机查找的方法:
设D是它们的最小公倍数。先找出A, B当中的较大者并存放在A中,
将较小者存放在B中, 让D=A,
当D能够整除B时,
则D是所求的最小公倍数;当D不能整除B,就逐次地让D增加A。例如:A=18,
B=12, 步骤如下:
① 让D=A (D=18)
② 当(D mod B)<>0
为真时 ( D不能整除B ) 就做
D=D+A, 重复②;
③ 当(D mod B)<>0
为假时结束循环,并输出D。
Pascal程序:
program Exam39;
var a,b,d,t
: word;
begin
write('input a,b:
'); readln(a , b);
if a<b then
begin
t:=a;
a:=b; b:=t
end;
d:=a;
while d mod b < >0
do {当条件为真时就做do后面的语句
}
inc(d,a);
writeln('[',
a, ' , ' , b, ']=', d) ;
readln
End.
Pascal语言的三种基本循环方式,
for循环对循环范围有明确规定,
且循环变量只能是递增加1或递减1自动计数控制;
而repeat--until循环和while--do循环比较灵活,
只要对条件表达式的值能控制满足一定要求就能组成循环,
但在循环体中必须有改变循环变量值的语句,
使条件判断(逻辑值)最终为True或flase,
让循环能够终止。
[例3.10]求自然数A,
B的最大公约数。
解:采用如下方法步骤:
(1)求A除以B的余数;
(2)当余数<>0就做n=a;
a=b; b=n mod b, 重复(1)和(2);
(3)当余数=0就结束循环,并输出b值。
比如a=18,
b=12时,处理步骤为:
(1) =
,得余数为6;
(2)
此余数不为零 ,让a = 12,
b = 6;
(3)
重复 =
, 得余数为0;
(4)
结束循环,输出6(余数为零时的b值即是所求的最大公约数)。
此方法称为辗转相除法求最大公约数。
Pascal程序:
program Exam310;
var a,b,
n : word;
begin
write('input a,b:
'); readln (a,b);
write('(', a,
' , ' , b, ')=' ) ;
while a mod b < >
0 do
begin
n:=a;
a:=b; b:=n mod b;
end;
writeln(b);
readln
End.
[例3.11]将一根长为369cm的钢管截成长为69cm和39cm两种规格的短料。在这两种规格的短料至少各截一根的前提下,
如何截才能余料最少。
解:设两种规格的短料分别为:
规格为69cm的x根,可在1至(369-39)/69范围循环取值;
规格为39cm的y根,用y
= (369-69*X)/39)计算;
余料R=369-69*X-39*Y。
①设最小余料的初始值min=369;
②在X循环范围内,每一个X值都计算出对应的Y和R;
③如果R<min,
就将R存入min, x存入n,
y存入m,记录余料最小时的x和y
;
④重复步骤②,当x值超出
((369—39)/
69) 时结束循环。
Pascal程序:
program exam311;
var x,y,r,min,n,m,a:
integer;
begin
min:=369;
a:=(369-39)
div 69; x:=1;
while x<=a do
begin
y:=(369-69*x)
div 39;
r:=369-69*x-39*y;
if r<min then
begin
min:=r;
n:=x; m:=y
end;
inc(x);
end;
writeln('min=',
min, ' x=', n, ' y=', m) ;
readln
end.
在有些情况中,
三种循环方法可以互相换用。
[例3.12]甲、乙、丙三人都是业余射击爱好者,
在一次练习中他们枪枪中靶:
甲射了八发子弹,取得225环成绩,乙射了七发,也取得225环;丙只射了六发,同样取得225环。下面是成绩表,请编程完成下表中空项的填数。
|
|
射子弹数 |
中50环有几发 |
中35环有几发 |
中25环有几发 |
成绩(环) |
|
甲 |
8 |
|
|
|
225 |
|
乙 |
7 |
|
|
|
225 |
|
丙 |
6 |
|
|
|
225 |
解:①设N为发射子弹数,
只有8, 7, 6三个数字,
正好又可用来代表甲、乙、丙;
②设A为中50环的子弹数,
最小为0, 最大为(225 div
50=4);
B为中35环的子弹数,
最小为0, 最大为(225 div
35=6);
C为中25环的子弹数,
C=N-A-B, 但必须C>0才可能正确;
③先让N=8, A取值(0~4),
B取值 (0~6)用循环逐个选定,
在C>0的情况下若能满足条件A*50+B*35+C*25=225就能确定一组填数。然后选N的下一数值,重复同样的过程。
Pascal程序:
program exam312;
var a,b,c,n,s
: integer;
begin
writeln('n':3,
'a':3, 'b':3, 'c':3, 's':5)
;
n:=8;
while n<=6 do
begin
a:=0;
while a < = 4
do
begin
b:=0;
while b < =
6 do
begin
c:=n-a-b;
if c>0
then
begin
s:=50*a+35*b+25*c;
if
s=225 then writeln(n:3,a:3,b:3,c:3,s:5);
end;
inc(b);
end;
inc(a);
end;
dec(n);
end;
readln
end.
程序运行结果获得两组填数答案。如果改用for循环,程序将更加简明:
Program Exam312_1;
Var a,b,c,n,s
: Integer;
Begin
Writeln('N':3,
'A':3, 'B':3, 'C':3, 'S':5)
;
for n:=8
downto 6 do {N取值8,7,6,并分别代表甲、乙、丙
}
for a:=0 to
4 do {中50环的可能范围
}
for b:=0
to 6 do {中30环的可能范围
}
begin
c:=n-a-b;
{ 计算中25环的子弹数
}
if c>0
then begin {如果不是负数 }
s:=50*a+35*6+25*c;
{计算总成绩
}
if
s=225 then writeln(n:3,a:3,b:3,c:3,s:5);
end
end;
readln
End.
习题3.3
1.求S=
1-1/2 +1/3-1/4+1/5-1/6+ ……(求前N项的和)
2. Faibonacci数列前几项为:
0,1,1,2,3,5,8,…,其规律是从第三项起,
每项均等于前两项之和。求前30项,
并以每行5个数的格式输出。
3.小球从100高处自由落下,着地后又弹回高度的一半再落下。求第20次着地时,
小球共通过多少路程?
4.某登山队员第一天登上山峰高度的一半又24米;
第二天登上余下高度的一半又24米;每天均如此。到第七天,距山顶还剩91米。求此山峰的高度?
5.给出某整数N,将N写成因数相乘的形式。如:
N=12,输出:
12=1*2*2*3.
6.出售金鱼者决定将缸里的金鱼全部卖出。第一次卖出全部金鱼的一半加二分之一条;第二次卖出剩余的三分之一加三分之一条金鱼;第三次卖出余下金鱼的四分之一加四分之一条;第四次卖出余下的五分之一加五分之一条金鱼。还剩下11条金鱼。当然,出售金鱼时都是整数条,不能有任何破损。求缸里原有的金鱼数?
7.外出旅游的几位朋友决定次日早晨共分一筐苹果。天刚亮,第一个人醒来,他先拿了一个,再把筐里的八分之一拿走;第二个人醒来,先拿两个,再把筐里的八分之一拿走;第三个人醒来,先拿三个,再拿走筐里的八分之一;…每个人依次照此方法拿出各人的苹果,最后筐里的苹果全部拿完,他们每人所拿到的苹果数正巧一样多。求原先筐里的苹果数和人数。
8.图中由6个圆圈构成三角形,每条边上有三个圈,
将自然数1--6 不重复地填入各圆圈位置上,使每条边圆圈上的数字之和相等,请编程输出所有的填法。
9.请编程显示出下面数字金字塔图形:
 |