第三章循环程序.docx
《第三章循环程序.docx》由会员分享,可在线阅读,更多相关《第三章循环程序.docx(28页珍藏版)》请在冰豆网上搜索。
![第三章循环程序.docx](https://file1.bdocx.com/fileroot1/2023-2/23/7de79df9-a672-40f1-b8f9-3bc05e7bd492/7de79df9-a672-40f1-b8f9-3bc05e7bd4921.gif)
第三章循环程序
第三章 循环程序
在编程中经常遇到需要多次规律相同的重复处理,这就是循环问题。
TurboPascal采用不同的循环方式来实现,常用的环循有三种:
for、repeat、while.
第一节 for循环
for循环是一种自动计数型循环。
[例3.1]试打印出1~20的自然数。
解:
①用a代表1~20各数,同时也用a兼作计数,以控制循环次数;
②让a从1开始;
③输出a;
④a自动计数(加1),如果未超越所规定的循环范围则重复步骤③,否则结束循环。
Pascal程序:
ProgramExam12;
Vara:
byte;
Begin
fora:
=1to20do
Writeln(a);
Readln
End.
程序中fora:
=1to20doWriteln(a);是for循环语句。
for循环语句有两种格式:
(1)for 循环变量:
=初值To终值do语句;
(2)for 循环变量:
=初值 downto终值do语句;
第
(1)种格式的初值小于等于终值,循环变量值按自动加1递增变化;
第
(2)种格式的初值大于或等于终值,循环变量值按自动减1递减变化。
for循环是(以递增1或以递减1)计数型循环。
比如:
若将[例3.1]程序改为倒计数(递减)循环,则输出20~1的自然数数:
ProgramExam31;
Vara:
byte;
Begin
fora:
=20downto1do
Writeln(a);
Readln
End.
[例3.2]打印出30至60的偶数。
]
解:
方法一:
=1\*GB3①设a表示30至60的所有的数,可用for循环列出;
=2\*GB3②用式子 amod2=0 筛选出其中的偶数并输出。
Pascal程序:
Programex32;
Vara:
integer;
Begin
Fora:
=30to60do
If(amod2=0)thenwriteln(a);
Readln;
End.
在这个程序中,for循环后的循环语句是一个条件分支语句。
方法二:
我们知道,在式子a=2*n中,若n取自然数1、2、3、…,时,则a依次得到偶数2、4、6、…。
因此要想得到30至60的偶数,就可以让上面式子中的n取15至30的自然数就可以了。
所以本题还可以按以下步骤处理:
=1\*GB3①设n表示15至30的所有自然数,可用for循环列出;
=2\*GB3②用式子 a:
=2*n 求出其中的偶数;
=3\*GB3③将结果输出至屏幕。
Pascal程序:
Programex32;
Begin
Forn:
=15to30do
Begin
a:
=2*n;
Writeln(a);
End;
Readln;
End.
[例3.3]自然数求和:
编一个程序,求从1至100的自然数的和。
解:
①令S=0;
②令a表示1至100的自然数,用循环列出;
③将这些自然数用公式S:
=S+a逐一累加到S中去;
=4\*GB3④循环结束后,S即为1至100的自然数的和,输出即可。
Pascal程序:
Programex33;
vars,a:
integer;
Begin
S:
=0;
Fora:
=1to100do
S:
=S+a;
Writeln(‘S=’,S);
Readln;
End.
[例3.4]一个两位数x,将它的个位数字与十位数字对调后得到一个新数y,此时y恰好比x大36,请编程求出所有这样的两位数。
解:
①用for循环列举出所有的两位数,x为循环变量;
②用公式a:
=xdiv10分离出x的十位数字;
③用公式b:
=xmod10分离出x的个位数字;
④用公式y:
=b*10+a合成新数y;
=5\*GB3⑤用式子y-x=36筛选出符合条件的数x并输出。
Pascal程序:
Programex34;
Begin
Forx:
=10to99do
Begin
a:
=xdiv10;
b:
=xmod10;
y:
=b*10+a;
ify-x=36thenwriteln(x);
End;
Readln;
End.
[例3.5]把整数3025从中剪开分为30和25两个数,此时再将这两数之和平方,(30+25)2=3025计算结果又等于原数。
求所有符合这样条件的四位数。
解:
设符合条件的四位数为N,它应当是一个完全平方数,用(a*a)表示。
①为了确保N=(a*a)在四位数(1000~9999)范围内,可确定a在32~99循环;
②计算N=a*a;将四位数N拆分为两个数n1和n2;
③若满足条件(n1+n2)*(n1+n2)=N就输出N。
Pascal程序:
ProgramExam35;
VarN,a,x,n1,n2:
Integer;
Begin
fora:
=32to99do
begin
N:
=a*a;
n1:
=Ndiv100;{拆取四位数的前两位数}
n2:
=N-n1*100;{拆取四位数的后两位数}
X:
=n1+n2;
ifx*x=Nthenwriteln(N);
end;
Readln
End.
[例3.6]用“*”号打印出如下的长方形图案。
*********
*********
*********
*********
解:
①上面给出的图例共有4行,我们可以用一个循环控制行的变化;
②在每行中又有9列,我们可以在前面控制行的循环中再套一个循环来控制列的变化。
Pascal程序:
Programex36;
Begin
Fora:
=1to4do{外循环控制行的变化}
Begin
Forb:
=1to9do{内循环控制列的变化}
write(‘*’);
Writeln;{输出一行的“*”后换行}
End;
Readln;
End.
程序中的循环对于a的每个值都包含着一个b=(1~9)次的内循环。
外循环fora将内循环forb包含在里面,称为for循环的嵌套。
嵌套形式如:
fora:
=n1ton2do
forb:
=m1tom2do循环体语句;
[例3.7]打印出九九乘法表:
解:
设a为被乘数,范围为1~9;b为乘数,范围为1~a;乘式为a*b=(a,b的乘积),则
a=1:
b=1~a1*1=1
a=2:
b=1~a2*1=22*2=4
a=3:
b=1~a3*1=33*2=63*3=9
a=4:
b=1~a4*1=44*2=84*3=134*4=16
:
:
a=9b=1~a9*1=99*2=18…9*9=81
⑴从上面分解的横行中看到共有9行,这里的“行”数变化与a的变化从1~9相同,可用a控制“行”的循环;
⑵每“行”里面相乘的次数与b的范围相关,由b控制每“行”里面的“内部”循环;
⑶内循环被包含在最里层,执行完每“行”的内部循环,就到下一“行”去执行新“行”里面的循环,每“行”都拥有形式相同的(b=1~a)内循环。
即每到一“行”都要执行该“行”的内循环。
这里所指的“行”可以理解成抽象的行,不一定是实际上具体对应的行,可以是一个处理“块”。
Pascal程序:
ProgramExam37;
Vara,b:
byte;
Begin
fora:
=1to9do{外循环}
begin
forb:
=1toado{内循环}
write(a,’*’,b,’=’,a*b,’’:
3);
writeln
end;
Readln
End.
根据这种格式还可以实现多层循环嵌套,例如:
fora:
=n1ton2do
forb:
=m1tom2do
forc:
=k1tok2do循环体语句;
[例3.8]从七张扑克牌中任取三张,有几种组合方法?
请编程输出所有组合形式。
解:
设每次取出三张分别为a,b,c。
用三重循环分别从1~7的范围里取值;为了排除取到重号,用(a-b)*(b-c)*(a-c)<>0进行判断。
Pascal程序:
programExam38;
constn=7;
vara,b,c,t:
integer;
Begin
t:
=0;
fora:
=1tondo
forb:
=1tondo
forc:
=1tondo
if(a-b)*(b-c)*(a-c)<>0then
Begin
inc(t);
writeln(a:
3,b:
3,c:
3)
End;
writeln(total:
t:
5);
readln
End.
[例3.9]数学上把除了1和它本身,没有别的数能够整除它的自然数叫做素数(或质数)。
现在由键盘输入一个自然数N,编程判断N是否是素数,是则输出“Yes”,否则输出“No”。
解:
根据定义,对于给定的自然数N,只需判断除1和它本身外,还有没有第三个自然数即可。
①令K从1循环至N;
②根据NmodK是否为0可统计K的约数的个数;
③若N的约数的个数超过2个,则判定N不是素数。
Pascal程序:
ProgramExam39;
Varn,m,k,t:
integer;
Begin
write(‘N=’);
ReadLn(N);
t:
=0;
fork:
=1toNdo{外循环}
ifNmodk=0thent:
=t+1;{如果N是奇数}
ift>2thenwriteln(‘No’)
elsewriteln(‘Yes’);
Readln;
End.
程序中的变量yse为布尔(或逻辑)类型(Boolean)。
布尔值只有两个:
True(真)False(假)
布尔值与条件判断结果为真(条件成立)或为假(条件不成立)的作用相同,常用于条件语句和循环语句中。
上面程序中用ifyesand(tmod7=0)thenwriteln;实现每行打印七个素数换行,程序中布尔变量yes为真,在逻辑上表示是素数;关系式(tmod7=0)的值为真时,表示该行输出素数巳是7个;用and将这两个“条件”连起来是作一种布尔(逻辑)运算。
Pascal共有四种逻辑运算符:
①and(与)两条件都为True时,其结果值为True;否则为False;
②or(或)两条件中只要有一个为True;其结果值为True;否则为False;
③xor(异或)两条件的逻辑值不相同时,其结果值为True;否则为False;
④not(非)条件为True时,其结果值为False;否则为True;(取反)
习题3.1:
1.打印出1至20的平方数表。
2.打印出100至200之间的奇数。
3.鸡兔同笼(用for循环程序完成)
4.一辆快车和一辆慢车开往同一地点,快车票价为18元,慢车票价为13.5元,共售出400张,共计5940元,求快车票和慢车票各多少张?
.
5.求出能被5整除的所有四位数的和。
6.在下面式子中的二个□内填入一个合适的同样的数字,使等式成立。
□3*6528=3□*8256
7.有一个三位数,它的各位数字之和的11倍恰好等于它自身,请编程求出这个三位数。
8.在自然数中,如果一个三位数等于自身各位数字之立方和,则这个三位数就称为是水仙花数。
如:
153=13+53+33,所以153是一个水仙花数。
求所有的水仙花数。
9.编程序打印出下列图案:
平行四边形等腰三解形 菱形
******* *
************
****************
****************
****************
10.编程打印出如下图案:
1
222
33333
4444444
555555555
11.有三种明信片:
第一种每套一张,售价2元;第二种每套一张,售价4元;第三种每套9张,售价2元。
现用100元钱要买100张明信片,要求每种明信片至少要买一套,问三种明信片应各买几套?
请输出全部购买方案。
12.某人想把一元钱换成伍分、贰分、壹分这样的零钱,在这三种零钱中每种零钱都至少各有一个的情况下,共有多少种兑换方案。
并打出这些方案。
13.
14.输出100以内的全部素数,要求每行显示5个。
15.A、B两个自然数的和、差、积、商四个数加起来等于243,求A、B两数。
16.百钱买百鸡:
今有钱100元,要买100只鸡,公鸡3元一只,母鸡1元一只,小鸡1元3只,若公鸡、母鸡和小鸡都至少要买1只,请编程求出恰好用完100元钱的所有的买鸡方案。
第二节 repeat循环
Repeat循环是直到型循环。
试将上一节的例3.1(打印出1~20的平方数表)程序改为repeat循环:
ProgramExam31_1;
Vara:
byte;
Begin
a:
=1;writeln('a':
8,'a*a':
8);
repeat
writeln(a:
8,a*a:
8);
inc(a);{改变a的值}
Untila>20;
Readln
Emd.
程序中的Repeat循环格式为:
repeat
循环体语句;
until条件表达式;{直到条件为真}
Repeat循环首先执行由Repeat和Until括起来的循环体语句,然后检查Until后面的条件表达式:
如果表达式结果为假,则继续执行循环体,接着继续检查Until后面的条件表达式,如此反复执行直到这个表达式结果为真时结束循环。
Repeat循环体语句必须有能改变Until后面条件表达式值的语句,并最终使这个条件表达式的值为真,使循环自动结束。
程序中inc(a)指令相当于a:
=a+1,常用的同类指令格式如下:
(1)inc(x)等同x:
=x+1;
(2)inc(x,n)等同x:
=x+n;
(3)dec(x)等同x:
=x—1;
(4)dec(x,n)等同x:
=x—n;
[例3.10]求两个自然数M和N的最大公约数。
解:
若自然数a既是M和约数,又是N的约数,则称a为M和N的公约数,其中最大的称为最大公约数。
为了求得最大公约数,可以从最大可能的数(如M或N)向下寻找,找到的第一个公约数即是最大公约数。
Pascal程序:
Programex310;
Begin
a:
=N+1;
Repeat
a:
=a-1;
Until(Mmoda=0)and(Nmoda=0);
writeln(a);
Readln;
End.
[例3.11]校体操队到操场集合,排成每行2人,最后多出1人;排成每行3人,也多出1人;分别按每行排4,5,6人,都多出1人;当排成每行7人时,正好不多。
求校体操队至少是多少人?
解:
①设校体操队为X人,根据题意X应是7的倍数,因此X的初值为7,以后用inc(x,7)改变X值;
②为了控制循环,用逻辑变量yes为真(True)使循环结束;
③如果诸条件中有一个不满足,yes的值就会为假(false),就继续循环。
Pascal程序:
programExam311;
varx:
word;yes:
boolean;
begin
x:
=0;
repeat
yes:
=true;inc(x,7);
ifxmod2<>1thenyes:
=false;
ifxmod3<>1thenyes:
=false;
ifxmod4<>1thenyes:
=false;
ifxmod5<>1thenyes:
=false;
ifxmod6<>1thenyes:
=false;
untilyes;{直到yes的值为真}
writeln('All=',x);readln
end.
程序中对每个X值,都先给Yes赋真值,只有在循环体各句对X进行判断时,都得到“通过”(此处不赋假值)才能保持真值。
[例3.12]从键盘输入一个整数X(X不超过10000),若X的各位数字之和为7的倍数,则打印“Yes”,否则中打印“No”。
解:
本题考察的是数字分离的方法,由于X的位数不定,所以以往的解法不能奏效,这是介绍一种取余求商法。
(1)用Xmod10分离出X的个位数字;
(2)用Xdiv10将刚分离的个数数字删除,并将结果送回给X;
(3)重复
(1)
(2)直到X=0。
Pascal程序:
Programex12;
varx,a,s:
integer;
begin
s:
=0;
repeat
a:
=xmod10;
x:
=xdiv10;
s:
=s+a;
untilx=0;
ifsmod7=0thenwriteln(‘Yes’)
elsewriteln(‘No’);
Readln;
end;
[例3.13]求1992个1992的乘积的末两位数是多少?
解:
积的个位与十位数只与被乘数与乘数的个位与十位数字有关,所以本题相当于求1992个92相乘,而且本次的乘积主下一次相乘的被乘数,因此也只需取末两位参与运算就可以了。
Pascal程序:
Programex313;
vara,t:
integer;
Begin
a:
=1;
t:
=0;
repeat
t:
=t+1;
a:
=(a*92)mod100;
untilt=1992;
writeln(a);
Readln;
End.
[例3.14]尼科彻斯定理:
将任何一个正整数的立方写成一组相邻奇数之和。
如:
33=7+9+11=2743=13+15+17+19=64
解:
从举例中发现:
(1)n3正好等于n个奇数之和;
(2)n个奇数中的最小奇数是从1开始的奇数序列中的第m个奇数,与n的关系为:
m=n(n—1)/2+1。
(3)奇数序列中第m个奇数的值为x,且x=2m—1,比如:
n=3时,m=3(3-1)/2+1=4,即3个奇数中最小的奇数是奇数序列中的第4个,它的值为x=(2m-1)=7,所以:
33=7+9+11。
(4)从最小的奇数值x开始,逐个递增2,连续n个,用t从1开始计数,直到t=n为止。
Pascal程序:
ProgramExam35;
Varn,m,x,t,s:
integer;
Begin
write(’inputn:
’);readln(n);{输入N}
m:
=(n*(n-1)div2)+1;{找到第m个奇数}
x:
=2*m-1;t:
=1;{算出第m个奇数的值x,是所求的第一个}
write(n’*’,n,’*’,n,’=’,x);{输出第一个}
s:
=x;{用S计算和}
ifn>1then
Repeat
inc(x,2);{计算下一个奇数}
write(’+’,x);{加上下一个奇数}
inc(t);inc(s,x);{计个数并累加和}
Untilt=n;{直到n个}
Writeln(’=’,s);
Readln
End.
[例3.15]猜价格:
中央电视台的“幸运52”栏目深受观众喜爱,其中的“猜商品价格”的节目更是脍炙人口,现在请你编一个程序模拟这一游戏:
由计算机随机产生200至5000之间的一个整数,作为某件商品的价格,然后由你去猜是多少,若你猜的数大了,则计算机输出提示“Gao”,若你猜的数小了,则计算机输出提示“Di”,然后你根据提示继续猜,直到你猜对了,计算机会提示“Ok”,并统计你猜的总次数。
解:
本题的游戏规则大家都清楚,要完成程序,必须把处理步骤理清:
(1)用随机函数Random产生200至5000之间的一个整数X;
(2)你猜一个数A;
(3)若A>X,则输出“Gao”;
(4)若A<X,则输出“Di”;
(5)若A=X则输出“Ok”;
(6)重复
(2)(3)(4)(5)直到A=X。
Pascal程序:
Programex315;
Vart,X,a:
integer;
Begin
Randomize;
X:
=Random(4800)+200;
t:
=0;
Repeat
t:
=t+1;
write(‘[‘,t,’]Qingcaiyigezhengshu:
‘);
readln(a);
ifa>xthenwriteln(‘Gao’);
ifaifa=xthenwriteln(‘Ok’);
UntilA=X;
Readln;
End.
习题3.2
1.求两个自然数M和N的最小公倍数。
(如果求三个或更多个数的最小公倍数呢?
应如何解决)
2.小会议室里有几条相同的长凳,有若干人参加开会。
如果每条凳子坐6人,结果有一条凳子只坐有3人;如果每条凳子坐5人,就有4人不得不站着。
求会议室里有多少人开会,有多少条长凳?
3.某动物饲养中心用1700元专款购买小狗(每只31元)和小猫(每只21元)两种小动物。
要求专款专用,正好用完,应当如何购买?
请输出所有方案。
4.某整数X加上100就成为一个完全平方数,如果让X加上168就成为另一个完全平方数。
求X?
5.某次同学聚会,老同学见面个个喜气洋洋,互相握手问好。
参加此次聚会者每人都与老同学握了一次手,共握903次,试求参加聚会的人数?
6.用自然数300,262,205,167分别除以某整数A,所得到的余数均相同。
求出整数A以及相除的余数?
7.1600年前我国的一部经典数学著作中有题:
“今有物,不知其数,三三数之,剩二;五五数之,剩三;七七数之,剩二,问物几何。
”求最小解。
8.编程求出所有不超过1000的数中,含有数字3的自然数,并统计总数。
9.阿姆斯特朗数:
如果一个正整数等于其各个数字的立方和,则该数称为阿姆斯特朗数(也称自恋数),如407=43+03+73,试编程求出1000以内的所有阿姆斯特朗数。
第三节 While循环
While循环是当型循环。
[例3.8]前面第一章[例1.2]的鸡兔同笼,头30,脚90,求鸡兔各几只?
在此用下面方法编程求解。
解:
设鸡为J只,兔为T只。
已知头为H,脚为F。
①